【发布时间】:2016-07-20 22:51:39
【问题描述】:
我有一个这样的数据框:
import pandas as pd
df = pd.DataFrame({
"time": [1, 2, 1, 2],
"site": ['a', 'a', 'b', 'b'],
"val1": [11, 12, 21, 22],
"val2": [101, 102, 201, 202]
})
df.set_index(['time', 'site'], inplace=True, append=False)
df = df.unstack("site")
print df
val1 val2
site a b a b
time
1 11 21 101 201
2 12 22 102 202
我想更改一些与布尔过滤器匹配的值。例如:
ix = df.val1 > 20
print ix
site a b
time
1 False True
2 False True
df.val1[ix] = 50 是很自然的尝试。这会完成预期的分配,但会发出警告:SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead。
所以现在我正在尝试使用df.loc 实现类似的目标。但是我找不到任何方法来使用df.loc 这种布尔掩码。这似乎是因为我使用的是分层列,即,如果我只有一组值 (val1),我不会遇到太多麻烦。不幸的是,docs 中没有很好地涵盖在分层列上使用布尔过滤器的分配。
我尝试过引用 df.loc[:,'val1',ix],但这给出了 IndexingError: Too many indexers。我已经尝试过df.loc[:,'val1'][ix] = 50,它有效,但给出了SettingWithCopyWarning。
我可以使用df.val1 = df.val1.where(~ix, other=50),但这似乎不直观、低效且不灵活(例如,它不能轻易扩展为现有值加 10)。
我应该使用其他一些索引方法来根据布尔掩码将值分配给数据帧的分层列吗?
已编辑以扩展问题:
我没有意识到这会是一个问题,但我实际上想根据 val1 和 val2 列中的值进行过滤并更改两组列中的值,如下所示:
ix = (df.val1 > 20) | (df.val2 < 102)
df.val1[ix] = 50
df.val2[ix] = 150
有没有一种简单的索引方法可以做到这一点?使用 numpy ndarrays 很容易,但使用 pandas 数据框似乎要复杂得多。
【问题讨论】:
-
您可以选择展平列吗?
标签: python pandas boolean-expression hierarchical