Pandas,获取行中所有三个值都可用的元素的总和

时间:2017-04-27 16:39:20

标签: python pandas

假设我有一个这样的数据框:

.navbar

首先,我想获得行的平均值,但我只想考虑所有橙色,苹果,丰满信息可用的行

其次,我试图获得不同水果之间的最大差异(例如,对于2008年的美国,它是12),如果至少只有一个水果信息可用。例如2011年意大利将是42

第三,我想重申那些在2008年至2010年间拥有所有年份信息的国家。 任何帮助都会得到很高的评价

3 个答案:

答案 0 :(得分:1)

首先有必要清理数据,转换为正确的类型&根据需要填充任何空值。 在此示例中,我们不需要任何填充

for ['Apple','Orange','Plump']中的col:     df [col] = pd.to_numeric(df [col],'coerce')

pandas.to_numeric函数的第二个参数定义了如何处理错误值。

然后我们可以逐行应用函数来实现所需的结果。

该函数应该接受一个系列,其中数据框的列名为键,应用逻辑,并返回一个元组,形成附加列。

df[['fruitmean', 'fruitdiff']] = df.apply(myfunc, axis=1)

我们将myfunc定义如下:

def myfunc(x):
    vals = pd.Series([x.Apple, x.Orange, x.Plump])
    valfilled = vals.fillna(0)
    nulls = vals.isnull().sum()
    fruitmean = vals.mean() if nulls == 0 else np.nan
    fruitdiff = valfilled.max() - valfilled.min() if nulls < len(vals) else np.nan
    return pd.Series([fruitmean, fruitdiff])

答案 1 :(得分:0)

  1. 正如评论中提到的那样,数字是字符串,由于像PRIVATE这样的字符很难转换为int,to_numeric(errors ='coerce')负责处理。

  2. 将年份转换为日期时间,以免日后计算。

  3. Pandas意味着仍然通过忽略一个或两个NaN细胞来找到平均值。所以np.where中的条件试图找出三列Orange,Apple和Plum的布尔总和是否为3。如果是,请找到平均值,否则返回Nan

    df [['Orange','Apple','Plump']] = df [['Orange','Apple','Plump']]。apply(pd.to_numeric,errors ='coerce')< / p>

    df.Year = pd.to_datetime(df.Year,format ='%Y')

    df ['mean'] = np.where(df [['Orange','Apple','Plump']]。notnull()。sum(axis = 1)== 3,df.mean(axis = 1).round(2),np.nan)

    df ['max_diff'] = df [['Orange','Apple','Plump']]。apply(lambda x:x.fillna(0).max() - x.fillna(0)。 min(),axis = 1)

答案 2 :(得分:0)

import pandas as pd
import numpy as np

pd.set_option('display.width', 1000)

cols = ['Country', 'Year', 'Orange', 'Apple', 'Plump']

data = [['US', 2008, 17, 29, 19],
        ['US', 2009, 11, 12, 16],
        ['US', 2010, 14, 16, 38],
        ['Spain', 2008, 11, None, 33],
        ['Spain', 2009, 12, 19, 17],
        ['France', 2008, 17, 19, 21],
        ['France', 2009, 19, 22, 13],
        ['France', 2010, 12, 11, 15],
        ['Italy', 2009, None, None, None],
        ['Italy', 2010, 15, 16, 17],
        ['Italy', 2011, 42, None, None]]

df = pd.DataFrame(data, columns=cols)

df['Any_NaN'] = df.apply(lambda row: any(np.isnan(r) for r in row['Orange':'Plump']), axis=1)
df['Any_number'] = df.apply(lambda row: any(not np.isnan(r) for r in row['Orange':'Plump']), axis=1)

df['Average'] = df[['Orange', 'Apple', 'Plump']].mean(axis=1)

df['Max'] = df[['Orange', 'Apple', 'Plump']].max(axis=1)
df['Min'] = df[['Orange', 'Apple', 'Plump']].min(axis=1)
df['Max_diff'] = df.apply(lambda row: row['Max'] - row['Min'], axis=1)
df['Desired_avg'] = df.apply(lambda row: np.nan if row['Any_NaN'] else row['Average'], axis=1)

print df

输出

   Country  Year  Orange  Apple  Plump Any_NaN Any_number    Average   Max   Min  Max_diff  Desired_avg
0       US  2008    17.0   29.0   19.0   False       True  21.666667  29.0  17.0      12.0    21.666667
1       US  2009    11.0   12.0   16.0   False       True  13.000000  16.0  11.0       5.0    13.000000
2       US  2010    14.0   16.0   38.0   False       True  22.666667  38.0  14.0      24.0    22.666667
3    Spain  2008    11.0    NaN   33.0    True       True  22.000000  33.0  11.0      22.0          NaN
4    Spain  2009    12.0   19.0   17.0   False       True  16.000000  19.0  12.0       7.0    16.000000
5   France  2008    17.0   19.0   21.0   False       True  19.000000  21.0  17.0       4.0    19.000000
6   France  2009    19.0   22.0   13.0   False       True  18.000000  22.0  13.0       9.0    18.000000
7   France  2010    12.0   11.0   15.0   False       True  12.666667  15.0  11.0       4.0    12.666667
8    Italy  2009     NaN    NaN    NaN    True      False        NaN   NaN   NaN       NaN          NaN
9    Italy  2010    15.0   16.0   17.0   False       True  16.000000  17.0  15.0       2.0    16.000000
10   Italy  2011    42.0    NaN    NaN    True       True  42.000000  42.0  42.0       0.0          NaN