如何在没有操作的情况下对 Pandas 数据框进行分组或聚合

Posted

技术标签:

【中文标题】如何在没有操作的情况下对 Pandas 数据框进行分组或聚合【英文标题】:how to groupby or aggregate Pandas dataframe without an operation 【发布时间】:2020-10-25 23:41:44 【问题描述】:

我有一个涉及 Pandas DataFrame 的具体情况如下:

df = pd.DataFrame('col1': ['group1','group1','group1'], 'value1':[0,0,0],'value2':['A','B','C'])

在这里,0 值可以解释为整列的“空白”或 NaN。

我要做的就是“按”“col1”值“分组”,在这种情况下只有“group1”,并获得一个数据框:

'col1'('group1')下的一个值 “value1”下的一个值 (0) 'value2' 下的 3 个值('A','B','C')

【问题讨论】:

这是你想要的吗? df.groupby(['col1', 'value1'], as_index=False).agg(list) 你能分享一下你想要的输出应该是什么样子吗? @laszlopanaflex 如果ABCvalue2 列下有 3 行,那么整个数据框需要 3 行,在其他列也是。目前尚不清楚您要问什么,我认为如果您包含所需输出的图片/代码会非常有帮助。 您是否只想设置索引? df.set_index(['col1', 'value1'], append=True).reorder_levels([1, 2, 0]) 【参考方案1】:

你可以试试set:

import pandas as pd

df = pd.DataFrame('col1': ['group1','group1','group1'], 'value1':[0,0,0],'value2':['A','B','C'])
print(df.groupby('col1').agg(set).reset_index())

输出:

     col1 value1     value2
0  group1    0  A, C, B

或者,如果您想将其保留为列表,您可以试试这个:

print(df.groupby('col1').agg(set).applymap(list).reset_index())

输出:

     col1 value1     value2
0  group1    [0]  ['A', 'C', 'B']

另外,如果你想在没有列表的情况下保留唯一编号,你可以尝试:

print(df.groupby('col1').agg(lambda x: x[0] if len(set(x))==1 else list(x)).reset_index())

输出:

     col1  value1     value2
0  group1       0  [A, B, C]

【讨论】:

之所以有效,是因为col1 中有一个唯一值,所以groupby 可以正常工作,但是如果存在group2 或@987654331 中的非唯一值,它将无法工作@我想。 你的意思是这样的数据框:df = pd.DataFrame('col1': ['group1','group1','group1','group2','group2','group2'], 'value1':[0,0,0,1,2,2],'value2':['A','B','C','A','B','C'])@CeliusStingher?或者你的意思是如果有一个不同于 0 的非唯一值,那么它将使 set 函数? 是的,没错,但它为 OP 完成了工作,所以我 +1 :)【参考方案2】:

这是一个想法,有点过于复杂,但它完成了工作:

import pandas as pd
df = pd.DataFrame('col1': ['group1','group1','group1'], 'value1':[0,0,0],'value2':['A','B','C'])
df_grouped = pd.DataFrame(x:str(list(set(df[x].values.tolist()))) for x in df,index=[0])

输出:

         col1 value1           value2
0  ['group1']    [0]  ['C', 'B', 'A']

但是,使用str 强制所有内容都在一行中并避免因数组长度不同而导致索引错误,可以使用ast.literal_eval() 撤消,将值返回到列表而不是字符串:

df_grouped = df_grouped.T
df_grouped = df_grouped[0].map(lambda x:ast.literal_eval(x)).to_frame().T

终于回来了:

       col1 value1     value2
0  [group1]    [0]  [C, B, A]

但使用正确的值类型(列表):

print(type(df_grouped.loc[0,'col1']))

输出:

<class 'list'>

【讨论】:

以上是关于如何在没有操作的情况下对 Pandas 数据框进行分组或聚合的主要内容,如果未能解决你的问题,请参考以下文章

如何在不更改特定列的情况下对数据框中的数据进行重新采样?

如何在没有重复数据的情况下对两个具有连接的表进行求和?

如何在没有任何统计数据(如 Pandas 中的平均值或计数)的情况下进行简单分组?

如何在不使用 Spark SQL 的情况下对 Spark 中的数据帧进行排序?

如何在没有ORM的情况下对DAO进行单元测试

如何在没有“排序”的情况下对对象向量进行排序