使用多列的熊猫数据框列表理解的内存有效方式

时间:2019-10-26 00:47:16

标签: python dataframe list-comprehension

我想在列表理解中的熊猫数据框的行上运行一个函数。 数据框可以具有不同数量的列。 如何利用数据框的这些列?

import  pandas as pd

df = {'chrom': ['chr1', 'chr1','chr1'], 'start': [10000, 10100, 12000], 'end':[10150,10120,12250], 'S1':[1, 1, 1],'S2':[2, 2, 2],'S3':[3, 3, 3] }
df = pd.DataFrame(data=df)
print(df)

def func(row):
    print(row)


[func(row) for row in zip(df['chrom'],df['start'],df['S1'],df['S2'],df['S3'])]

如何以内存有效的方式执行此操作?这样我们就不会对大数据帧产生任何内存错误。

4 个答案:

答案 0 :(得分:1)

所示的代码具有极高的内存效率,并且应该比基于iterrow的解决方案要快。

但是从您的评论来看,不是导致内存错误的代码...有问题的代码是:

df[list(df.columns.values)].values()

或:

df[list(df.columns.values)].to_numpy(copy=False)

因为两者都涉及数据帧值的完整副本,除非所有列都具有相同的dtype。

如果您要处理未知数量的列,安全的方法是:

[func(row) for row in zip([df[i].values for i in df.columns])]

这里不需要复制,因为df[i].values将返回基础的numpy数组。


顺便说一句,如果您只需要使用一次返回列表的值,您甚至可以通过使用生成器而不是列表来节省一些内存:

(func(row) for row in zip([df[i].values for i in df.columns]))

答案 1 :(得分:1)

感谢您的回答。

同时,我发现以下解决方案:

df_columns = list(df.columns.values)
[func_using_list_comp(
                row,
                var1,
                var2,
                var3,
                ...,
                df_columns) for row in df[df_columns].values]

通过这种方式,我不需要使用zip函数并使它适用于任意数量的列。

我希望这也可以提高内存效率。 顺便说一句,每次处理一行时,我都会在var1,var2,var3中累积。

如果我使用生成器而不是列表,它将对我的内存使用产生多大影响,并且在处理完所有行之后是否将获得所有累积的数据?

因为,在处理完所有行之后,我将返回这些var1,var2,var3。

答案 2 :(得分:0)

您的列表理解方法似乎比需要的方法更加混乱,尤其是考虑到熊猫数据帧具有iterrows()方法。您可以使用以下代码替换您的版本:

for index, row in df.iterrows():
    func(row)

但是我只建议上述方法,因为您的函数似乎只打印出该行。根据您的func的实际情况,您可能需要考虑使用df.apply()

df.apply(func, axis=1)

答案 3 :(得分:0)

在您的示例中,打印整行,用[0]或*只是再次删除numpy帧:

[func(*row) for row in zip(df[['chrom','start','S1','S2','S3']].to_numpy())]

[func(row[0]) for row in zip(df[['chrom','start','S1','S2','S3']].to_numpy())]

['chr1' 10000 1 2 3]
['chr1' 10100 1 2 3]
['chr1' 12000 1 2 3]

仅打印第三列:

[func(row[0][2]) for row in zip(df[['chrom','start','S1','S2','S3']].to_numpy())]

1
1
1

ps:这最后还具有控制台输出[None, None, None],但这仅仅是因为列表理解内的print()结果为None,它不属于打印结果。

另请参阅:

编辑:

请使用df.iloc和df.loc而不是df [[...]],请参见Selecting multiple columns in a pandas dataframe