有效地设置行子集的值

时间:2016-03-17 14:34:45

标签: pandas

我想知道更改数据框中行子集中值的最佳方法。 假设我想将value为真的行selected中的值加倍。

In [1]: import pandas as pd
In [2]: df = pd.DataFrame({'value': [1, 2, 3, 4], 'selected': [False, False, True, True]})
In [3]: df
Out[3]: 
  selected  value
0    False      1
1    False      2
2     True      3
3     True      4

有几种方法可以做到这一点:

# 1. Subsetting with .loc on left and right hand side:
df.loc[df['selected'], 'value'] = df.loc[df['selected'], 'value'] * 2

# 2. Subsetting with .loc on left hand side:
df.loc[df['selected'], 'value'] = df['value'] * 2

# 3. Using where()
df['value'] = (df['value'] * 2).where(df['selected'], df['value'])

如果我只在左侧进行子集(选项2),Pandas是否会实际计算所有行,然后丢弃除所选行之外的所有行的结果?

在评估方面,使用locwhere之间有什么区别吗?

1 个答案:

答案 0 :(得分:1)

您的#2选项是最标准和建议的方法。你的#1选项也没问题,但是额外的代码是不必要的,因为ix/loc/iloc被设计为通过布尔选择并进行必要的对齐以确保它仅适用于你想要的子集。

# 2. Subsetting with .loc on left hand side:
df.loc[df['selected'], 'value'] = df['value'] * 2

如果您不在左侧使用ix/loc/iloc,我们可能会出现一些问题,我们不想在简单的答案中使用。因此,使用ix/loc/iloc通常是最安全和最常推荐的方式。您的选项#3没有任何问题,但它是三者中最不可读的。

你应该知道的一个更快,更可接受的替代方案是numpy' where()函数:

df['value'] = np.where( df['selected'], df['value'] * 2, df['value'] )

第一个参数是选择或掩码,第二个参数是如果为True则分配的值,第三个参数是如果为false则分配的值。如果您想在选择为False的情况下创建或更改值,那么它特别有用。