我有一个看起来像这样的DataFrame:
| Age | Married | OwnsHouse |
| 23 | True | False |
| 35 | True | True |
| 14 | False | False |
| 27 | True | True |
我想找到已婚并拥有房屋的所有人的最高年龄。答案是35。我首先想到的是:
df_subset = df[df['Married'] == True and df['OwnsHouse'] == True]
max_age = df_subset.max()
但是,数据集很大(50MB),我担心这会花费两次数据集,因此计算量很大。
我的第二个想法是要做:
max_age = 0
for index, row in df.iterrows():
if(row[index]['Married] and row['index']['OwnsHouse'] and row[index]['Age] > max_age):
max_age = row[index]['Age']
有更快的方法吗?
答案 0 :(得分:5)
您的第一种方法是可靠的,但这是一个简单的选择:
df[df['Married'] & df['OwnsHouse']].max()
Age 35.0
Married 1.0
OwnsHouse 1.0
dtype: float64
或者,只是年龄:
df.loc[df['Married'] & df['OwnsHouse'], 'Age'].max()
# 35
如果您有多个布尔列,我建议您进行一些扩展,
df[df[['Married', 'OwnsHouse']].all(axis=1)].max()
Age 35.0
Married 1.0
OwnsHouse 1.0
dtype: float64
在哪里
df[['Married', 'OwnsHouse']].all(axis=1)
0 False
1 True
2 False
3 True
dtype: bool
与...相同,
df['Married'] & df['OwnsHouse']
0 False
1 True
2 False
3 True
dtype: bool
但是,不是手动查找N个布尔掩码的AND,而是.all
为您完成
query
是另一种选择:
df.query("Married and OwnsHouse")['Age'].max()
# 35
它不需要计算遮罩的中间步骤。
您的方法足够快,但是如果要进行微优化,可以使用numpy进行以下操作:
# <= 0.23
df[(df['Married'].values & df['OwnsHouse'].values)].max()
df[df[['Married', 'OwnsHouse']].values.all(axis=1)].max()
# 0.24+
df[(df['Married'].to_numpy() & df['OwnsHouse'].to_numpy())].max()
df[df[['Married', 'OwnsHouse']].to_numpy().all(axis=1)].max()
Age 35.0
Married 1.0
OwnsHouse 1.0
dtype: float64
尽管您可能只想要年龄。做
df.loc[(df['Married'].to_numpy() & df['OwnsHouse'].to_numpy()), 'Age'].max()
# 35
如果您想要更多的numpy,请执行以下操作:
df.loc[(
df['Married'].to_numpy() & df['OwnsHouse'].to_numpy()), 'Age'
].to_numpy().max()
# 35
或者更好,丢掉熊猫,
df['Age'].to_numpy()[df['Married'].to_numpy() & df['OwnsHouse'].to_numpy()].max()
# 35