【问题标题】:Convert column values for a group of data frame rows into a list in the column将一组数据框行的列值转换为列中的列表
【发布时间】:2020-07-12 11:13:20
【问题描述】:

对于这个问题,我们来举个例子。我有一个如下所示的数据框 (df.head()):

   Unnamed: 0  PacketTime  FrameLen  FrameCapLen  ...  Speed  Delay  Loss  Interval
0           1    0.056078       116          116  ...     25      0     0         0
1           2    0.056106        66           66  ...     25      0     0         0
2           3    2.058089       116          116  ...     25      0     0         2
3           4    2.058115        66           66  ...     25      0     0         2
4           5    4.060316       116          116  ...     25      0     0         4

[5 rows x 23 columns]

如您所见,这些组位于 Interval 列旁边。我知道 pandas 有一个df.groupby(colname),但我想做的是对间隔行进行分组,以便将列值一起列出。这将给出一个示例输出,如下所示:

   Unnamed: 0  PacketTime  FrameLen  FrameCapLen  ...  Speed  Delay  Loss  Interval
0           1    0.000028       116,66          116,66  ...     25,25      0,0     0,0         0
1           2    0.000026        116,66           116,66  ...     25,25      0,0     0,0         2
...

[5 rows x 23 columns]

如您所见,期望的最终结果是将列分组到间隔组的列表中,并组合数据包时间,使得每个间隔组的值为max(PacketTime)-min(PacketTime)

【问题讨论】:

  • 为什么输出中的Unnamed: 0 列聚合为12?我猜应该是1, 23, 4,对吧?

标签: python pandas dataframe


【解决方案1】:

这是两个独立的任务。 对于两者,让我们使用 groupby operation which does the following process:

基于单个列将单个数据框拆分为多个数据框。对每个数据框应用操作。将生成的数据框拼接在一起。

第一份工作:

对于除 PacketTime 之外的所有列,每个间隔都有一行 - 其中每个值都是两个值的列表。

我们想把东西拼接到一个列表中。所以让我们使用series.to_list()。由于我不知道的原因,打电话给df.apply(lambda s: s.to_list() ) 是行不通的。 Pandas 自动将列表转换回普通列 - 但是在行上调用它会返回我们想要的:一系列列表。因此,我们将列转换为行,将 to_list 应用于行(以前的列)。

例子

df.T.apply(lambda series: series.to_list(), axis='columns')

结果:

PacketTime     [0.056078, 0.056106, 2.058089, 2.058115, 4.060...
FrameLen                       [116.0, 66.0, 116.0, 66.0, 116.0]
FrameCapLen                    [116.0, 66.0, 116.0, 66.0, 116.0]
Unnamed: 3                             [nan, nan, nan, nan, nan]
Speed                             [25.0, 25.0, 25.0, 25.0, 25.0]
Delay                                  [0.0, 0.0, 0.0, 0.0, 0.0]
Loss                                   [0.0, 0.0, 0.0, 0.0, 0.0]
Interval                               [0.0, 0.0, 2.0, 2.0, 4.0]

这正是我们想要的每个区间。那么让我们将其定义为一个函数,然后将其应用于每个区间,对吧?!


import pandas as pd

df = pd.read_excel('example.xlsx')


def to_list(df):
    return df.T.apply(lambda x: x.to_list(), axis='columns')


df_other = df.groupby('Interval')\
            .apply(to_list)\
            .drop(columns='PacketTime')

第二份工作:

为了计算持续时间,我们只需要一个函数,取最小时间和最大时间并推导出它们的时间长度:

     
def min_max(s):
    return s.max()-s.min()

现在我们只需应用它并将两个 dfs 连接在一起:

s_Interval = df.groupby('Interval')['PacketTime']\
            .apply(min_max)
final_df = pd.concat([df_other,s_Interval], axis= 'columns')

我们最终得到:


print(final_df.to_markdown())
|   Interval | FrameLen      | FrameCapLen   | Unnamed: 3   | Speed        | Delay      | Loss       | Interval   |   PacketTime |
|-----------:|:--------------|:--------------|:-------------|:-------------|:-----------|:-----------|:-----------|-------------:|
|          0 | [116.0, 66.0] | [116.0, 66.0] | [nan, nan]   | [25.0, 25.0] | [0.0, 0.0] | [0.0, 0.0] | [0.0, 0.0] |      2.8e-05 |
|          2 | [116.0, 66.0] | [116.0, 66.0] | [nan, nan]   | [25.0, 25.0] | [0.0, 0.0] | [0.0, 0.0] | [2.0, 2.0] |      2.6e-05 |
|          4 | [116.0]       | [116.0]       | [nan]        | [25.0]       | [0.0]      | [0.0]      | [4.0]      |      0       |




【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-13
    • 1970-01-01
    • 2022-12-20
    • 1970-01-01
    • 2018-06-10
    • 1970-01-01
    相关资源
    最近更新 更多