我有一个下面的数据框,并尝试创建三个更大,更少和计数的新列。条件是计算有多少值大于/小于平均值并将它们相加。
df =
APPL Std_1 Std_2 Std_3 Mean
0 ACCMGR 106.8754 130.1600 107.1861 114.750510
1 ACCOUNTS 121.7034 113.4927 114.5482 116.581458
2 AUTH 116.8585 112.4487 115.2700 114.859050
def make_count(comp_cols, mean_col):
count_d = {'greater': 0, 'less': 0}
for col in comp_cols:
if col > mean_col:
count_d['greater'] += 1
elif col < mean_col:
count_d['less'] += 1
return count_d['greater'], count_d['less'], (count_d['greater'] + count_d['less'])
def apply_make_count(df):
a,b,c,*d= df.apply(lambda row: make_count([row['Std_1'], row['Std_2'], row['Std_3']], row['Mean of Std']), axis=1)
df['greater'],df['less'],df['count']=a,b,c
apply_make_count(df)
但我得到错误显示:
13 df['greater'],df['less'],df['count']=list(zip(a,b,c))
ValueError: Length of values does not match length of index
输出我想成为
df =
APPL Std_1 Std_2 Std_3 Mean greater less count
0 ACCMGR 106.8754 130.1600 107.1861 114.750510 1 2 3
1 ACCOUNTS 121.7034 113.4927 114.5482 116.581458 1 2 3
2 AUTH 116.8585 112.4487 115.2700 114.859050 2 1 3
尝试
df['greater'] = (df.iloc[:, 1:4].values > df[['Mean']].values).sum(axis=1)
df['less'] = (df.iloc[:, 1:4].values < df[['Mean']].values).sum(axis=1)
df['count'] = df.iloc[:, 1:4].count(1)
APPL Std_1 Std_2 Std_3 Mean greater less count
0 ACCMGR 106.8754 130.1600 107.1861 114.750510 1 2 3
1 ACCOUNTS 121.7034 113.4927 114.5482 116.581458 1 2 3
2 AUTH 116.8585 112.4487 115.2700 114.859050 2 1 3
好像你需要简单
sub_df = df[['Std_1', 'Std_2', 'Std_3']]
df['greater'] = sub_df.gt(df.Mean.values).sum(1) # same as (sub_df > df.Mean.values).sum(1)
df['less'] = sub_df.lt(df.Mean.values).sum(1)
df['count'] = sub_df.count(1)
APPL Std_1 Std_2 Std_3 Mean greater less count
0 ACCMGR 106.8754 130.1600 107.1861 114.750510 1 2 3
1 ACCOUNTS 121.7034 113.4927 114.5482 116.581458 1 2 3
2 AUTH 116.8585 112.4487 115.2700 114.859050 2 1 3
您收到错误是因为您将,*d
添加到您提供的原始解决方案中。
# the way you rewrote it
a,b,c,*d= df.apply(lambda row: make_count([row['Std_1'], row['Std_2'], row['Std_3']], row['Mean of Std']), axis=1)
df['greater'], df['less'], df['count'] = a, b, c
# the code you were provided
a, b, c = df.apply(lambda row: make_count([row['Std_1'], row['Std_2'], row['Std_3']], row['Mean']), axis=1)
df['greater'], df['less'], df['count'] = list(zip(a, b, c))
你在这里提供的解决方案link to your previous question
此外:
您获得的原始解决方案是最快的解决方案:
%timeit(apply_make_count(df))
1.93 ms ± 279 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
新解决方案:
def test():
df['greater'] = (df.iloc[:, 1:4].values > df[['Mean']].values).sum(axis=1)
df['less'] = (df.iloc[:, 1:4].values < df[['Mean']].values).sum(axis=1)
df['count'] = df.iloc[:, 1:4].count(1)
%timeit(test())
2.6 ms ± 35.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
def test2():
sub_df = df[['Std_1', 'Std_2', 'Std_3']]
df['greater'] = sub_df.gt(df.Mean.values).sum(1) # same as (sub_df > df.Mean.values).sum(1)
df['less'] = sub_df.lt(df.Mean.values).sum(1)
df['count'] = sub_df.count(1)
%timeit(test2())
2.82 ms ± 263 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)