我尝试使用函数对数据帧列表进行子集化。该函数将仅需要返回例如具有Z-列的总数> df的df。 14和X列值(行0-4)比这5个值的平均值低30%或高于30%。因此,在下面的示例中,将返回df1而不返回df2。
可以这样做,用这些条件评估每个数据帧吗?有人能指出我正确的方向吗?
N = 5
np.random.seed(0)
df1 = pd.DataFrame(
{'X':np.random.uniform(0,5,N),
'Y':np.random.uniform(0,5,N),
'Z':np.random.uniform(0,5,N),
})
df2 = pd.DataFrame(
{'X':np.random.uniform(0,5,N),
'Y':np.random.uniform(0,5,N),
'Z':np.random.uniform(0,5,N),
})
df1.loc['total'] = df1.sum()
df2.loc['total'] = df2.sum()
df_list = (df1, df2)
X Y Z
0 2.744068 3.229471 3.958625
1 3.575947 2.187936 2.644475
2 3.013817 4.458865 2.840223
3 2.724416 4.818314 4.627983
4 2.118274 1.917208 0.355180
total 14.176521 16.611793 14.426486
--------------------------------------
X Y Z
0 0.435646 4.893092 3.199605
1 0.101092 3.995793 0.716766
2 4.163099 2.307397 4.723345
3 3.890784 3.902646 2.609242
4 4.350061 0.591372 2.073310
total 12.940682 15.690299 13.322267
答案 0 :(得分:2)
可以使用列表理解,具有2个陈述的条件。
Z条件非常简单易行。关于X条件,我创建了一个小函数,如果数据帧与条件匹配则返回True,否则为False。
In [156]: def check_X(df):
...: avg = df.drop('total')['X'].mean()
...: for val in df.drop('total')['X']:
...: if val/avg < 0.7 or val/avg > 1.3: #30% more or less
...: return False
...: return True
...:
因此,我们可以通过以下方式获得预期结果:
In [157]: [df for df in df_list if df.drop('total')['Z'].sum() > 14 and check_X(df)]
Out[157]:
[ X Y Z
0 2.744068 3.229471 3.958625
1 3.575947 2.187936 2.644475
2 3.013817 4.458865 2.840223
3 2.724416 4.818314 4.627983
4 2.118274 1.917208 0.355180
total 14.176522 16.611794 14.426486]
编辑:一个更好的单线解决方案,不使用任何用户定义的功能:
In [205]: [df for df in df_list if df['Z'].sum() > 14 and ((df['X'] > df['X'].mean()*0.7) & (df['X'] < df['X'].mean()*1.3)).all()]
Out[205]:
[ X Y Z
0 2.744068 3.229471 3.958625
1 3.575947 2.187936 2.644475
2 3.013817 4.458865 2.840223
3 2.724416 4.818314 4.627983
4 2.118274 1.917208 0.355180]
为简单起见,我放弃了总数&#39;在处理前从两个df行:
In [204]: df_list = [df.drop('total') for df in df_list]
答案 1 :(得分:1)
如果您有数据框列表,则使用列表推导有条件地选择数据框,您可以使用切片(iloc[0:-1]
排除最后一行)。
new_list= [x for x in df_list if (x.loc['total','Z']>14) and
((x.iloc[0:-1]['X'] > x.iloc[0:-1]['X'].mean()*0.7) & (x.iloc[0:-1]['X'] < x.iloc[0:-1]['X'].mean()*1.3)).all()]
输出:
[ X Y Z 0 2.744068 3.229471 3.958625 1 3.575947 2.187936 2.644475 2 3.013817 4.458865 2.840223 3 2.724416 4.818314 4.627983 4 2.118274 1.917208 0.355180 total 14.176521 16.611793 14.426486]