【问题标题】:Error when calling a groupby object inside a Pandas DataFrame在 Pandas DataFrame 中调用 groupby 对象时出错
【发布时间】:2018-03-05 01:31:40
【问题描述】:

我有这个数据框:

    person_code  #CNAE   growth   size 
0           231     32     0.54     32
1           233     43     0.12    333
2           432     32     0.44     21
3           431     56     0.32     23
4           654     89     0.12     89
5           764     32     0.20    211
6           434     32     0.82     90

我需要创建一个名为“top3growth”的新列。为此,我需要为每一行检查 df 的 #CNAE 并添加一个额外的列,指出哪些是该 CNAE 增长最快的 3 个人(它将在 df 数据帧内添加一个数据帧)。要创建“top3dfs”,我正在使用这个 groupby:

a=sql2.groupby('#CNAE',group_keys=False).apply(pd.DataFrame.nlargest,n=3,columns='growth')

(这个解决方案来自this question。)

应该是这样的:

    person_code  #CNAE   growth   size              top3growth ...
0 .         231     32     0.54     32       [df_top3_type_32]
1 .         233     43     0.12    333       [df_top3_type_43]
2 .         432     32     0.44     21       [df_top3_type_32]                     
3 .         431     56     0.32     23       [df_top3_type_56]
4 .         654     89     0.12     89       [df_top3_type_89]
5 .         764     32     0.20    211       [df_top3_type_32]
6 .         434     32     0.82     90       [df_top3_type_32]
...

df_top3_type_32 应该如下所示(例如):

     person_code  #CNAE  growth  size
6 .          434    32    0.82    90
0 .          231    32    0.54    32
2 .          432    32    0.44    21

我正在尝试使用以下方法解决我的问题:

df['top3growth']=np.nan
for i in df.index:
    df['top3growth'].loc[i]=a[a['#CNAE'] == df['#CNAE'].loc[i]]

但我得到了:

ValueError: Incompatible indexer with DataFrame

有人知道发生了什么吗? 有没有更有效的方法(不使用 for 循环)?

【问题讨论】:

  • (旁白:社区已经讨论过home-made tags in titles,并决定将标题作为自然英语更好。使用标签系统进行标签。谢谢)。
  • @jpp 与该问题无关。
  • 是的,确实如此。它清楚地解释了为什么你想做的是一个坏主意。这是一个经典的 XY 问题。解释你想要达到的目标,而不是如何使用不明智的方法。
  • 也许,df.loc[i,'top3growth'] = a[a['#CNAE'] == df.at[i,'#CNAE']]

标签: python pandas pandas-groupby


【解决方案1】:

有一种方法,将 a 转换为 dict ,然后将其映射回来

#a=df.groupby('#CNAE',group_keys=False).apply(pd.DataFrame.nlargest,n=3,columns='growth')
df['top3growth']=df['#CNAE'].map(a.groupby('#CNAE').apply(lambda x : x.to_dict()))
df
Out[195]: 
   person_code  #CNAE  growth  size  \
0          231     32    0.54    32   
1          233     43    0.12   333   
2          432     32    0.44    21   
3          431     56    0.32    23   
4          654     89    0.12    89   
5          764     32    0.20   211   
6          434     32    0.82    90   
                                          top3growth  
0  {'person_code': {0: 231, 2: 432, 6: 434}, 'gro...  
1  {'person_code': {1: 233}, 'growth': {1: 0.12},...  
2  {'person_code': {0: 231, 2: 432, 6: 434}, 'gro...  
3  {'person_code': {3: 431}, 'growth': {3: 0.32},...  
4  {'person_code': {4: 654}, 'growth': {4: 0.12},...  
5  {'person_code': {0: 231, 2: 432, 6: 434}, 'gro...  
6  {'person_code': {0: 231, 2: 432, 6: 434}, 'gro...  

创建新列后,如果要将单个单元格转换回数据框

pd.DataFrame(df.top3growth[0])
Out[197]: 
   #CNAE  growth  person_code  size
0     32    0.54          231    32
2     32    0.44          432    21
6     32    0.82          434    90

【讨论】:

  • 谢谢@Wen。那 df['top3growth']=df['#CNAE'].map(a.groupby('#CNAE').apply(lambda x : x.to_dict())) 会在 for 循环内吗?跨度>
  • @abutremutante nope ,这里不需要for循环,可以认为是merge :-)
  • 似乎是一个很好的解决方案,但我不确定您的队列是否过滤了增长最快的 3 人(df 是一个非常大的数据框)。我试试看
  • @abutremutante 我正在使用您自己的代码在此处创建数据
  • 我试图将其放入 groupby 行:.apply(pd.DataFrame.nlargest,n=3,columns='growth') 但无法做到。有没有办法把它包括在这里?这是唯一缺少的部分
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-05
  • 2019-07-04
  • 2014-09-18
  • 2018-01-15
  • 2018-01-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多