操作 pandas 数据框列中的列表(例如除以另一列)
Manipulate lists in a pandas data frame column (e.g. divide by another column)
我有一个 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:如果您想知道为什么我将列表存储在列中:这些是傅里叶变换的结果振幅。
为什么我不为每个频率使用一列?
- 为每个频率创建一个新列非常慢
- 我的项目中有不同的采样率和 FFT-window 大小,有多组频率。
压缩两列,通过 product and starmap 的组合将列 a 中的每个条目与其对应的列 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 有所帮助 - 看看 link 看看是否有帮助.
我会将列表转换为 numpy 数组:
df['c'] = df['a'].apply(np.array) / df['b']
您将在 c 列中得到 np.array
s。如果你真的需要列表,你必须将它们转换回来
df['c'] = df['c'].apply(list)
我有一个 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:如果您想知道为什么我将列表存储在列中:这些是傅里叶变换的结果振幅。
为什么我不为每个频率使用一列?
- 为每个频率创建一个新列非常慢
- 我的项目中有不同的采样率和 FFT-window 大小,有多组频率。
压缩两列,通过 product and starmap 的组合将列 a 中的每个条目与其对应的列 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 有所帮助 - 看看 link 看看是否有帮助.
我会将列表转换为 numpy 数组:
df['c'] = df['a'].apply(np.array) / df['b']
您将在 c 列中得到 np.array
s。如果你真的需要列表,你必须将它们转换回来
df['c'] = df['c'].apply(list)