【问题标题】:How do I apply transformations to list of pandas dataframes?如何将转换应用于熊猫数据框列表?
【发布时间】:2016-05-14 00:26:06
【问题描述】:

我有一堆属于少数逻辑分组的 pandas DataFrame,但所有这些都有一些重叠的列。如果我可以将函数列表(例如下面funcs 中的函数)应用到整个 DataFrame 列表,将会节省大量时间。

# Make example DataFrames
df_a = pd.DataFrame({'col_a': [1, 1, 2], 'col_b': [1, 1, 2], 'col_c': [1, 1, 2], 
                     'col_d': [1, 2, 3], 'col_e': [1, 2, 3], 'col_f': [1, 2, 3], 
                     'foo': 'foo', 'bar': 'bar', 'baz': 'baz'})
df_b = pd.DataFrame({'col_a': [4, 5, 5], 'col_b': [4, 5, 5], 'col_c': [4, 5, 5], 
                     'col_d': [4, 5, 6], 'col_e': [4, 5, 6], 'col_f': [4, 5, 6],
                     'foo': 'foo', 'bar': 'bar', 'baz': 'baz'})
df_c = pd.DataFrame({'col_a': [7, 7, 7], 'col_b': [7, 7, 7], 'col_c': [7, 7, 7], 
                     'col_d': [7, 8, 9], 'col_e': [7, 8, 9], 'col_f': [7, 8, 9], 
                     'foo': 'foo', 'bar': 'bar', 'baz': 'baz'})

# Make list of a bunch of DataFrames
data_sets_a = [df_a, df_b, df_c]

# Drop some columns (this works as expected on each DataFrame)
[d.drop(['foo', 'bar', 'baz'], axis=1, inplace=True) for d in data_sets_a]

# List of functions to apply to overlapping DataFrame columns
funcs = {'col_d': 'count', 'col_e': 'min', 'col_f': 'sum'}

# Group by and aggregate with funcs dict (does not work)
[d.groupby(['col_a', 'col_b', 'col_c']).agg(funcs, inplace=True).reset_index() for d in data_sets_a]

data_sets_a

使用dropinplace=True 在列表理解中的DataFrames 列表上按我的预期工作,但它不适用于groupbyagg——列表中的DataFrames 保持不变。

[   col_a  col_b  col_c  col_d  col_e  col_f
 0      1      1      1      1      1      1
 1      1      1      1      2      2      2
 2      2      2      2      3      3      3,
    col_a  col_b  col_c  col_d  col_e  col_f
 0      4      4      4      4      4      4
 1      5      5      5      5      5      5
 2      5      5      5      6      6      6,
    col_a  col_b  col_c  col_d  col_e  col_f
 0      7      7      7      7      7      7
 1      7      7      7      8      8      8
 2      7      7      7      9      9      9]

更改dropinplace=True 值符合我的预期,但似乎与groupbyagg 并没有什么不同。

有人可以解释为什么这两个列表推导会产生不同的结果,或者告诉我一个更好的方法来获得我正在寻找的结果吗?

将函数映射到DataFrame列表的代码有问题吗?

我已经阅读了 pandas 的文档和谷歌搜索了一段时间,并尝试了各种方法,例如 querymaplambda 组合,但无济于事。

【问题讨论】:

  • 你试过concatenating你的数据框了吗?
  • 我想将它们分开,因为它们是针对不同人群的单独测试,并且每个数据框以后都需要不同的转换。
  • 实际上每个列表中大约有 10 个数据帧和 3 个列表,但是处理过程有足够的重叠,我应该能够一次对整个列表应用一些转换。
  • drop 在数据帧上定义,而 agg 在 groupby 对象上定义。我不相信它有一个就地选项。你可以做df_a, df_b, df_c = [d.groupby(['col_a', 'col_b', 'col_c']).agg(funcs).reset_index() for d in data_sets_a]
  • 所以基本上你想要的是count for col_dmin for col_esum for col_f 基于groupby(['col_a', 'col_b', 'col_c'])。这是你想要的输出吗?

标签: python python-3.x pandas dataframe


【解决方案1】:

解决方案

for i in range(len(data_sets_a)):
    cols = ['col_a', 'col_b', 'col_c']
    gb = data_sets_a[i].groupby(cols)
    data_sets_a[i] = gb.agg(funcs, inplace=1).reset_index()

说明

如果您的列表理解,您返回了正确的对象,但没有将它们放置在您想要的位置。 inplace=True 没有扩充列表 data_sets_a 中指向的同一个对象。

我所做的是为列表的每个元素分配正确的扩充。

另一种方法是使用你已经拥有的:

data_sets_a = [
    d.groupby(
        ['col_a', 'col_b', 'col_c']
    ).agg(funcs, inplace=True).reset_index() for d in data_sets_a
]

只需将新列表分配给旧列表即可。

【讨论】:

    【解决方案2】:

    如果我正确理解您的问题,那么问题出在您的funcs 上。你可以这样尝试:

    def funcs(x):
        col_d = x['col_d'].count()
        col_e = x['col_e'].min()
        col_f = x['col_f'].sum()
        return pd.Series([col_d, col_e, col_f], index= ['col_d', 'col_e', 'col_f'] )
    

    那么你可以使用apply(funcs)

    [d.groupby(['col_a', 'col_b', 'col_c']).apply(funcs).reset_index() for d in data_sets_a]
    

    输出将是:

    [   col_a  col_b  col_c  col_d  col_e  col_f
     0      1      1      1      2      1      3
     1      2      2      2      1      3      3,
        col_a  col_b  col_c  col_d  col_e  col_f
     0      4      4      4      1      4      4
     1      5      5      5      2      5     11,
        col_a  col_b  col_c  col_d  col_e  col_f
     0      7      7      7      3      7     24]
    

    【讨论】:

      猜你喜欢
      • 2019-10-12
      • 2022-01-19
      • 2017-08-26
      • 1970-01-01
      • 2021-04-19
      • 1970-01-01
      • 1970-01-01
      • 2019-02-07
      相关资源
      最近更新 更多