【问题标题】:Keeping one (invariant) row from each dataframe group从每个数据帧组中保留一个(不变)行
【发布时间】:2017-02-28 23:08:06
【问题描述】:

我有一个 pandas DataFrame,我按三列 A, B, C 的组合对其进行了分组。

grouped = df.groupby(["A", "B", "C"])

另外几列D, E, F, G 对于每组的所有元素(保证)相同,而其他列X, Y 在每组内各不相同。 (我已经知道哪些列是固定的,哪些是变化的。)

我想构建一个数据框,每组包含一行,并且仅包含不变列 A, B, C, D, E, F, G 的值。最直接的方法是什么?由于有很多相同的值,我宁愿指定要省略哪些列,而不是相反。

我想出了“聚合”,方法是从每个组中选择一行,然后在单独的步骤中删除不需要的列:

thinned = grouped.aggregate(lambda x: x.iloc[0])
del thinned["X"], thinned["Y"]

这样做的目的是将不变值与我计算的几个新汇总值组合在一个数据框中,每个(当前)组有一行。

thinned["newAA"] = grouped.apply(some_function)
thinned["newBB"] = grouped.apply(other_function)
...

但我怀疑肯定有一种不那么迂回的方式。

【问题讨论】:

  • 为什么不首先选择groupby 之前的那些列?例如df[df.columns.difference(['X','Y'])].groupby(['A','B','C'])
  • 这是个好主意,但我还需要与在不同的分组列上计算的数据框合并。所以它可能会起作用,但我需要注意索引。
  • 对我来说,分组然后删除您不感兴趣的列似乎是多余的,最好在操作之前不要选择它们
  • 嗯,我我有兴趣从删除的列中计算值;我只需要结果中的不变列。无论如何,difference() 方法很值得了解。
  • 您还可以做的另一件事是对所有不变的 cols 进行 groupby 并传递 as_index=False 或 reset_index 但如果您只是想删除骗子,那么已经有一个现有的方法可以做到这一点,它最终取决于你想要达到的目标。

标签: python pandas


【解决方案1】:

您可以使用GroupBy.first() 仅选择每个组的第一条记录。比如这个

import pandas

df = pandas.DataFrame({
    'A': [1, 1, 2, 2, 3, 3], 
    'B': [1, 1, 1, 2, 2, 2], 
    'C': [2, 2, 3, 3, 1, 1]
})
print(df.groupby(['A', 'B'])['C'].first())

结果

A  B
1  1    2
2  1    3
   2    3
3  2    1
Name: C, dtype: int64

【讨论】:

    【解决方案2】:

    我觉得你需要drop_duplicates:

    df = pd.DataFrame({'A':[7,4,4],
                       'B':[7,4,4],
                       'C':[7,4,4],
                       'D':[7,4,4],
                       'E':[7,4,4],
                       'F':[7,4,4],
                       'G':[7,4,4],
                       'X':[1,2,8],
                       'Y':[5,7,0]})
    
    print (df)
       A  B  C  D  E  F  G  X  Y
    0  7  7  7  7  7  7  7  1  5
    1  4  4  4  4  4  4  4  2  7
    2  4  4  4  4  4  4  4  8  0
    
    #filter by subset
    cols = ["A", "B", "C", "D","E","F", "G"]
    df1 = df.drop_duplicates(subset=cols)[cols]
    print (df1)
       A  B  C  D  E  F  G
    0  7  7  7  7  7  7  7
    1  4  4  4  4  4  4  4
    
    #remove unnecessary columns
    df2 = df.drop(['X','Y'], axis=1).drop_duplicates()
    print (df2)
       A  B  C  D  E  F  G
    0  7  7  7  7  7  7  7
    1  4  4  4  4  4  4  4
    

    【讨论】:

      【解决方案3】:

      我猜你在这里有很多选择,或多或少优雅。 首先,你关心'X'和'Y'吗?如果你不这样做,因为你要在最后删除它们,你可以简单地使用drop_duplicates

      new_df = df[['A', 'B', 'C', 'D', 'E', 'F', 'G']].drop_duplicates()
      # this will keep only the unique values of the above columns
      

      【讨论】:

        猜你喜欢
        • 2023-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-29
        相关资源
        最近更新 更多