pandas.DataFrame.sum()参数“min_count”等效于0.22之前的pandas版本

时间:2018-01-29 12:58:55

标签: python pandas numpy dataframe pandas-groupby

假设我有一些格式为

的数据框
     id        time  value
0   100  2012-04-01    2.3
1   100  2012-04-02    3.4
2   100  2012-04-03    1.4
3   100  2012-04-04    5.6
4   200  2012-04-01    NaN
5   200  2012-04-02    2.9
6   200  2012-04-03    2.8
7   200  2012-04-04    1.9
8   300  2012-04-01    3.1
9   300  2012-04-02    NaN
10  300  2012-04-03    2.5
11  300  2012-04-04    1.2

所以我们有时间序列的id(这里是100,200,300),对于每个时间序列,我们有相应的4个不同时间步长的值(2012-04-01到2012-04-04)。

我想创建一个函数来获取这样的数据帧,将其转动然后对行进行求和。但是,我希望此函数具有一个参数,该参数决定如何在其中一个值为nan值的情况下求和。我有3个案例:

  • nan被认为是0(例如a + b + NaN = a + b)
  • 如果nan在总和中,则总和为零(例如a + b + NaN = 0)
  • 如果nan在总和中,则总和为nan(例如a + b + NaN = Nan)

我的尝试

首先,看here我知道我可以使用df.pivot('time', 'id', 'value')获取

来转动df
    time      100    200    300
2012-04-01    2.3    3.0    3.1
2012-04-02    3.4    2.9    4.2
2012-04-03    1.4    2.8    2.5
2012-04-04    5.6    1.9    1.2

然后该功能看起来像

def pivot_sum(df, method = 'zero'):
    # NaN are treated as zero: a + b + NaN = a + b
    if method == 'zero':
        return pd.DataFrame(df.groupby('time')['value'].sum())
    else:
        # First we pivot it
        pivoted = df.pivot('time', 'id', 'value')
        # Then we choose
        if method == 'nan_make_zero_sum':
            # Do something
        elif method == 'nan_make_nan_sum':
            # DO something else

我完全不知道如何继续。我注意到使用groupby选项的行为就好像nan值被视为零。但是,我不知道如何实施其他的。

注意:我注意到新版本的pandas有一个参数min_count可能很有用(https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.sum.html),但我有0.21版本,由于其他问题,更改版本不是一个很好的解决方案。

修改

我设法编写它以便它适用于pandas版本0.22,但是我想知道如何编写类似于以前版本的函数。无论如何它在这里

def sum_values(df, method = 'skip'):
    if method == 'skip':
        # Then we treat NaN values as zeros
        return pd.DataFrame(df.groupby('time')['value'].sum())

    else:
        # First we pivot the df
        df_pivoted = df.pivot('time', 'id', 'value')
        # Then we check
        if method == 'nan_sum':
            return pd.DataFrame(df_pivoted.sum(axis = 1, min_count = df_pivoted.shape[1])).rename(columns = {0:'value'})
        elif method == 'zero_sum':
            # do the same as above
            return pd.DataFrame(df_pivoted.sum(axis = 1, min_count = df_pivoted.shape[1])).rename(columns = {0:'value'}).fillna(0)

编辑2 - 看起来像什么

鉴于上述功能,这就是流程的样子。

我有一个数据框

     id        time  value
0   100  2012-04-01    2.3
1   100  2012-04-02    3.4
2   100  2012-04-03    1.4
3   100  2012-04-04    5.6
4   200  2012-04-01    NaN
5   200  2012-04-02    2.9
6   200  2012-04-03    2.8
7   200  2012-04-04    1.9
8   300  2012-04-01    3.1
9   300  2012-04-02    NaN
10  300  2012-04-03    2.5
11  300  2012-04-04    1.2

并应用上述功能

sum_values(df, method = 'skip')返回

            value
   time        
2012-04-01    5.4
2012-04-02    6.3
2012-04-03    6.7
2012-04-04    8.7

sum_values(df, method = 'nan_sum')返回

            value
   time        
2012-04-01    NaN
2012-04-02    NaN
2012-04-03    6.7
2012-04-04    8.7

sum_values(df, method = 'zero_sum')返回

            value
   time        
2012-04-01    0.0
2012-04-02    0.0
2012-04-03    6.7
2012-04-04    8.7

1 个答案:

答案 0 :(得分:1)

我创建了以下3个函数,可以提供所需的输出:

功能1

import numpy as np
def sum_val(df):
    df1=df.copy()
    df1['value'] = pd.to_numeric(df1['value'], errors='coerce')
    df2=df1.fillna(0.0)
    df2['sum_nan']=df2.groupby(['time_val']).transform('sum')
    df3=df2.drop('value', inplace=False, axis=1)
    df4=df3.drop_duplicates()
    return (df4)
sum_val(df)

输出:

     time_val  sum_nan
0  2012-04-01      5.4
1  2012-04-02      6.3
2  2012-04-03      6.7
3  2012-04-04      8.7

功能2

def sum_nan(df):

    df1=pd.DataFrame()
    df1=df.copy()

    df1['sum_nan']=df1.groupby(['time_val']).transform('sum')

    df2=df1.drop('value', inplace=False, axis=1)
    df2=df2.drop_duplicates()
    return df2



 sum_nan(df)

输出:

time_val    sum_nan
0   2012-04-01  NaN
1   2012-04-02  NaN
2   2012-04-03  6.7
3   2012-04-04  8.7

功能3

def sum_0(df):

    df1=pd.DataFrame()
    df1=df.copy()
    df1['sum_nan']=df1.groupby(['time_val']).transform('sum')
    df2=df1.drop('value', inplace=False, axis=1)
    df2=df2.replace(np.nan,0)
    df3=df2.drop_duplicates()
    return(df3)

sum_0(df)

输出:

     time_val  sum_nan
0  2012-04-01      0.0
1  2012-04-02      0.0
2  2012-04-03      6.7
3  2012-04-04      8.7