【问题标题】:Pandas group by : Include all rows even the ones with empty column valuesPandas group by:包括所有行,即使是具有空列值的行
【发布时间】:2018-04-03 03:47:19
【问题描述】:

我正在使用 Pandas 并尝试测试一些东西以完全理解某些功能。

在使用以下代码从 csv 加载所有内容后,我正在对数据进行分组和聚合:

s = df.groupby(['ID','Site']).agg({'Start Date': 'min', 'End Date': 'max', 'Value': 'sum'})
print(s)

它适用于以下文件:

但它不适用于此文件:

对于第二个文件,我只获取 56311 ID 的数据。原因是某些列具有空值。但这应该没关系。我还没有找到任何相关的东西。我只找到了如何排除空列。

除了这个问题,在分组之前我应该​​考虑哪些主要的事情?是否有可能因为格式(日期或数字)而排除行?

【问题讨论】:

    标签: python pandas pandas-groupby


    【解决方案1】:

    在 Pandas 版本 > 1.1.0 中,您可以传递 dropna=False 以保留 NaN 值(请参阅 pandas.DataFrame.groupby)。

    In [1]: import pandas as pd
    
    In [2]: import numpy as np
    
    In [3]: pd.__version__
    Out[3]: '1.1.2'
    
    In [4]: df = pd.DataFrame([[1, 2], [3, 4], [np.nan, 6]], columns=["A", "B"])
    
    In [5]: df
    Out[5]: 
         A  B
    0  1.0  2
    1  3.0  4
    2  NaN  6
    
    In [6]: df.groupby("A").mean()
    Out[6]: 
         B
    A     
    1.0  2
    3.0  4
    
    In [7]: df.groupby("A", dropna=False).mean()
    Out[7]: 
         B
    A     
    1.0  2
    3.0  4
    NaN  6
    

    【讨论】:

      【解决方案2】:

      如果NaNs 在by 参数的列中存在问题,则删除组。

      因此需要将NaN 替换为不在Site 列中的某个值,并且在groupby 替换回NaNs 之后:

      感谢Zerogroupby 中使用fillna 简化解决方案:

      df1= (df.groupby([df['ID'],df['Site'].fillna('tmp')])
              .agg({'Start Date': 'min', 'End Date': 'max', 'Value': 'sum'})
              .reset_index()
              .replace({'Site':{'tmp': np.nan}}))
      

      如果需要NaNs in MultiIndex:

      s = (df.groupby([df['ID'],df['Site'].fillna('tmp')])
             .agg({'Start Date': 'min', 'End Date': 'max', 'Value': 'sum'})
             .rename(index={'tmp':np.nan}))
      

      示例:

      df = pd.DataFrame({'A':list('abcdef'),
                         'Site':[np.nan,'a',np.nan,'b','b','a'],
                         'Start Date':pd.date_range('2017-01-01', periods=6),
                         'End Date':pd.date_range('2017-11-11', periods=6),
                         'Value':[7,3,6,9,2,1],
                         'ID':list('aaabbb')})
      
      print (df)
         A   End Date ID Site Start Date  Value
      0  a 2017-11-11  a  NaN 2017-01-01      7
      1  b 2017-11-12  a    a 2017-01-02      3
      2  c 2017-11-13  a  NaN 2017-01-03      6
      3  d 2017-11-14  b    b 2017-01-04      9
      4  e 2017-11-15  b    b 2017-01-05      2
      5  f 2017-11-16  b    a 2017-01-06      1
      

      df1= (df.groupby([df['ID'],df['Site'].fillna('tmp')])
              .agg({'Start Date': 'min', 'End Date': 'max', 'Value': 'sum'})
              .reset_index()
              .replace({'Site':{'tmp': np.nan}}))
      
      print (df1)
        ID Site   End Date Start Date  Value
      0  a    a 2017-11-12 2017-01-02      3
      1  a  NaN 2017-11-13 2017-01-01     13
      2  b    a 2017-11-16 2017-01-06      1
      3  b    b 2017-11-15 2017-01-04     11
      
      s = (df.groupby([df['ID'],df['Site'].fillna('tmp')])
             .agg({'Start Date': 'min', 'End Date': 'max', 'Value': 'sum'})
             .rename(index={'tmp':np.nan}))
      
      print (s)
                End Date Start Date  Value
      ID Site                             
      a  a    2017-11-12 2017-01-02      3
         NaN  2017-11-13 2017-01-01     13
      b  a    2017-11-16 2017-01-06      1
         b    2017-11-15 2017-01-04     11
      

      【讨论】:

      • 也许你可以df.groupby(['ID', df['Site'].fillna('tmp')])...而不是为单行分配?
      • @jezrael 我发布了一个新的有趣问题,我真的被卡住了。如果你有时间:)
      • 你觉得this 吗?我认为有必要加倍 groupby,不幸的是
      猜你喜欢
      • 2010-12-06
      • 1970-01-01
      • 1970-01-01
      • 2016-04-02
      • 2021-12-17
      • 1970-01-01
      • 2020-12-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多