【问题标题】:How to convert group.iterrows() loop result to dataframe in Pandas如何将 group.iterrows() 循环结果转换为 Pandas 中的数据框
【发布时间】:2022-01-04 00:23:52
【问题描述】:

考虑以下数据:

df['rank']=df.groupby('Contact').cumcount()
df.set_index('rank', inplace=True, drop=True)               
df
Contact New Old DateNew DateOld moddate User Rank
0 mary False True 2021-01-12 11:00:00 NaT 2021-01-12 12:48:00 sys
1 mary True False NaT 2021-01-12 11:00:00 2021-01-12 12:47:00 Rob
2 mary False True 2021-01-12 11:00:00 NaT 2021-01-12 12:45:00 sys
3 mary True False NaT 2021-11-29 11:00:00 2021-01-12 12:44:00 Rob
0 john True False NaT 2021-12-10 11:00:00 2021-12-10 16:15:00 Tina
1 john False True 2021-12-10 11:00:00 NaT 2021-12-10 15:30:00 sys
2 john True False NaT 2021-12-10 11:00:00 2021-12-10 15:29:00 Rina
3 john False True 2021-12-10 11:00:00 NaT 2021-12-10 12:37:00 sys

如何将以下结果转换为数据框? dfpandas.core.frame.DataFramegrppandas.core.groupby.generic.DataFrameGroupBy

grp = df.groupby('Contact')
for name,group in grp:
        for i,row in group.iterrows():
            
            if i < len(group)-1:
                if (group.loc[i,'Old'] == group.loc[i+1,'New']):
                    if group.loc[i,'User'] == 'sys':
                        if group.loc[i+1,'User'] !='sys':
                            group.loc[i,'Overwritten']= True
                            
                        else:
                            group.loc[i,'Overwritten']= False
                    else:
                        group.loc[i,'Overwritten']= False
                              
                else:
                    group.loc[i,'Overwritten']= False
    
        print(group)

上述解决方案可能不是最好的方法,也许我可以使用shift 函数。但我想知道如何将循环中的groupby 结果作为数据框,以便进行更多过滤/分析。我还是熊猫的新手。 谢谢。

【问题讨论】:

  • 您确定 New(字符串名称)和 Old(布尔值)具有可比性吗?
  • @Parfait 有没有办法可以将 print(group) 结果作为数据框获取?当我在 jupyter 的新行中运行 'group' 时,它将 groupby 结果的最后一个块作为数据帧返回,新列 'overwritten' ,我希望整个 groupby 结果作为新数据帧。你能帮忙吗?谢谢
  • 在循环之前简单地初始化一个列表,然后将每个group 附加到列表中。然后在 list 上运行 pd.concat 以将组重新堆叠在一起。

标签: python pandas pandas-groupby


【解决方案1】:

通过按联系人排序并使用shift列计算布尔列覆盖,避免groupbyiterrows的需要。实际上,您可以将所有 if 展平为单个逻辑检查:

calc_df = (
    df.sort_values('Contact')           # SORT BY GROUPING VARIABLE
      .reset_index(drop=True)           # RESET INDEX FOR SHIFT COLS
      .assign(                          # ADD SHIFT HELPER COLUMNS
          Contact_ = lambda df: df['Contact'].shift(-1),
          New_ = lambda df: df['New'].shift(-1),
          User_ = lambda df: df['User'].shift(-1),
          Overwritten = lambda df: (    # CALCULATE BOOLEAN COLUMN
               (df['Contact'] == df['Contact_']) &
               (df['Old'] == df['New_']) &
               (df['User'] == 'sys') &
               (df['User_'] != 'sys')
          )
      )
)

calc_df

【讨论】:

  • 谢谢,这很有帮助,但是有没有办法可以像上面那样使用循环并将 groupby 结果返回到 / 作为数据框,这将有助于我继续进行进一步的数据过滤和分析。
  • 这个解决方案避免了循环,实际上用shift 跟进你的最后一段。与一般 Python 不同,在 pandas 和 numpy 编程中应避免循环以进行矢量化操作。当数据变得更大时,您会感谢这种方法!
猜你喜欢
  • 2020-11-27
  • 2017-11-22
  • 2018-01-21
  • 1970-01-01
  • 2018-08-10
  • 2012-08-16
  • 1970-01-01
  • 2023-01-29
相关资源
最近更新 更多