【问题标题】:Manipulate lists in a pandas data frame column (e.g. divide by another column)处理 pandas 数据框列中的列表(例如,除以另一列)
【发布时间】:2020-05-28 08:48:53
【问题描述】:

我有一个 pandas 数据框,其中有一列包含列表。我希望将每一行中的每个列表元素除以另一列中的标量值。在以下示例中,我希望将 a 中的每个元素除以 b:

              a   b
0  [11, 22, 33]  11
1  [12, 24, 36]   2
2  [33, 66, 99]   3

因此产生以下结果:

              a   b                   c
0  [11, 22, 33]  11     [1.0, 2.0, 3.0]
1  [12, 24, 36]   2   [6.0, 12.0, 18.0]
2  [33, 66, 99]   3  [11.0, 22.0, 33.0]

我可以通过以下代码实现这一点

import pandas as pd

df = pd.DataFrame({"a":[[11,22,33],[12,24,36],[33,66,99]], "b" : [11,2,3]})

result = {"c":[]}
for _, row in df.iterrows():
    result["c"].append([x / row["b"] for x in row["a"]])

df_c = pd.DataFrame(result)
df = pd.concat([df,df_c], axis="columns")

但是对行进行显式迭代并将结果收集到字典中,将其转换为数据帧,然后连接到原始数据帧似乎效率低下且不优雅

有人有更好的解决方案吗?

在此先感谢您的欢呼!


PS:如果您想知道我为什么要将列表存储在列中:这些是傅立叶变换的结果幅度。

为什么我不对每个频率使用一列?

  1. 为每个频率创建一个新列非常慢
  2. 在我的项目中,由于采样率和 FFT 窗口大小不同,因此存在多组频率。

【问题讨论】:

    标签: python pandas list performance fft


    【解决方案1】:

    压缩两列,通过productstarmap的组合,将col a中的每个条目与其对应的col b中的条目分开,并将迭代器转换回列表。

    from itertools import product,starmap
    from operator import floordiv
    df['c'] = [list(starmap(floordiv,(product(num,[denom])))) 
               for num, denom in zip(df.a,df.b)]
    
    
            a           b       c
    0   [11, 22, 33]    11  [1, 2, 3]
    1   [12, 24, 36]    2   [6, 12, 18]
    2   [33, 66, 99]    3   [11, 22, 33]
    

    或者,你可以在迭代中使用 numpy 数组:

    df['c'] = [list(np.array(num)/denom) for num, denom in zip(df.a,df.b)]
    

    感谢@jezrael 的建议 - 所有这些都可能是不必要的,因为 scipy 有 FFT 的东西 - 查看链接,看看它是否有帮助。

    【讨论】:

    • 不熟悉 FFT。你可以提供那个。也给了我学习的机会
    • 看来我错了,好像是FFT的输出。+1,对不起
    • 澄清:我对 FFT 没有任何疑问。我只是在解释,为什么我会将列表存储在数据框列中,因为我希望有人会质疑这种设计选择。
    • 你的第二个选择最吸引我。小基准测试:在一个示例性真实数据集上,耗时约 4.9 秒,而我笨拙的尝试耗时约 121 秒
    • 感谢您的反馈;如果您以某种方式找到更快的替代方案,请分享
    【解决方案2】:

    我会将列表转换为 numpy 数组:

    df['c'] = df['a'].apply(np.array) / df['b']
    

    您将在 c 列中获得np.arrays。如果您确实需要列表,则必须将它们转换回来

    df['c'] = df['c'].apply(list)
    

    【讨论】:

    • 这比公认的答案更具可读性,但速度要慢 6.1 秒。非常感谢!
    猜你喜欢
    • 2021-04-28
    • 1970-01-01
    • 2016-05-28
    • 2019-06-07
    • 2021-11-04
    • 2018-02-05
    • 2019-10-07
    • 1970-01-01
    相关资源
    最近更新 更多