python - Pandas 按列和掩码索引
问题描述
我有以下数据框:
import numpy as np
import pandas as pd
np.random.seed(398)
df = pd.DataFrame(np.random.randn(20, 3), columns=['a', 'b', 'c'])
我希望使用以下索引按列和行值索引数据框:
row_indexer = (df.index > 5)
col_indexer = (df > -1) & (df < 1)
并修改这些位置的值。因此,基本上数据帧中索引大于 5 且值介于 -1 和 1 之间的所有情况。这可以通过以下方式完成:
df[row_indexer[:, None] & col_indexer] = np.nan
没有问题。但是,我现在想在包含另外 3 个名为["a_str", "b_str", "c_str"]
. 请参阅以下内容:
str_cols = [i + "_str" for i in df.columns]
df[str_cols] = 'blank'
并使用与之前的值完全相同的掩码,修改数据框中的所有_str
列。因此,使用相同的示例,如果原始数据帧以下列方式修改数字列:
a b c
0 -1.810802 -0.776590 -0.495147
1 1.381038 0.235168 2.334671
2 0.406279 -1.571401 1.011139
3 -1.200217 -1.013983 -0.040659
4 1.261759 0.863896 0.228914
5 0.696952 -1.384910 1.204492
6 NaN 1.180030 NaN
7 -2.027946 NaN NaN
8 NaN NaN NaN
9 NaN NaN NaN
10 -1.389175 2.263662 NaN
11 NaN -1.077414 NaN
12 NaN -1.696859 -1.049889
13 -1.057308 NaN NaN
14 NaN NaN -1.206815
15 NaN NaN NaN
16 2.063715 -1.981503 NaN
17 NaN -1.022833 1.957646
18 1.315031 NaN 1.425088
19 -1.860641 NaN NaN
然后字符串列将如下所示:
a_str b_str c_str
0 blank blank blank
1 blank blank blank
2 blank blank blank
3 blank blank blank
4 blank blank blank
5 blank blank blank
6 new string blank new string
7 blank new string new string
8 new string new string new string
9 new string new string new string
10 blank blank new string
11 new string blank new string
12 new string blank blank
13 blank new string new string
14 new string new string blank
15 new string new string new string
16 blank blank new string
17 new string blank blank
18 blank new string blank
19 blank new string new string
问题是我不知道如何在原始数据帧上执行此操作,我只能在副本上执行此操作:
x = row_indexer[:, None] & col_indexer
x.columns = [i + "_str" for i in x.columns]
a = df[['a_str', 'b_str', 'c_str']]
a[x] = 'new string'
重现此内容的完整代码如下:
import numpy as np
import pandas as pd
np.random.seed(398)
df = pd.DataFrame(np.random.randn(20, 3), columns=['a', 'b', 'c'])
row_indexer = (df.index > 5)
col_indexer = (df > -1) & (df < 1)
x = row_indexer[:, None] & col_indexer
df[row_indexer[:, None] & col_indexer] = np.nan
print(df)
str_cols = [i + "_str" for i in df.columns]
df[str_cols] = 'blank'
x.columns = [i + "_str" for i in x.columns]
a = df[['a_str', 'b_str', 'c_str']]
a[x] = 'new string'
print(a)
编辑:
想补充一点,这在技术上可以通过以下方式解决:
df[str_cols] = a
但是,这意味着需要将内存加倍作为原始数据帧的副本,理想情况下我希望避免这种情况。我很确定内存已经因为掩码(df[row_indexer[:, None] & col_indexer
)而增加了一倍,所以我想尽可能避免内存爆炸
解决方案
在这种情况下采取的基本方法是创建一个布尔掩码并将此掩码的视图作为numpy
数组获取,然后选择mask
您希望替换值的列
mask = row_indexer[:, None] & col_indexer
df[str_cols] = df[str_cols].mask(mask.values, 'new string')
为什么使用mask.values
而不是mask
?
由于 pandas 会根据索引对齐数据,因此列的名称mask
必须与 的名称匹配,str_cols
才能使 mask 方法正常工作。要解决这个问题,有两个选项,要么重命名 mask 对应的列str_cols
,另一个选项是创建一个 mask 视图作为 numpy 数组(因为 numpy 数组没有命名信息),因此索引对齐不再是问题和面具会正常工作。
a b c a_str b_str c_str
0 -1.810802 -0.776590 -0.495147 blank blank blank
1 1.381038 0.235168 2.334671 blank blank blank
2 0.406279 -1.571401 1.011139 blank blank blank
3 -1.200217 -1.013983 -0.040659 blank blank blank
4 1.261759 0.863896 0.228914 blank blank blank
5 0.696952 -1.384910 1.204492 blank blank blank
6 NaN 1.180030 NaN new string blank new string
7 -2.027946 NaN NaN blank new string new string
8 NaN NaN NaN new string new string new string
9 NaN NaN NaN new string new string new string
10 -1.389175 2.263662 NaN blank blank new string
11 NaN -1.077414 NaN new string blank new string
12 NaN -1.696859 -1.049889 new string blank blank
13 -1.057308 NaN NaN blank new string new string
14 NaN NaN -1.206815 new string new string blank
15 NaN NaN NaN new string new string new string
16 2.063715 -1.981503 NaN blank blank new string
17 NaN -1.022833 1.957646 new string blank blank
18 1.315031 NaN 1.425088 blank new string blank
19 -1.860641 NaN NaN blank new string new string
推荐阅读
- ubuntu - 如何找到依赖于已弃用库的 PHP 模块?
- java - GC 如何将不可访问对象标记为已不可访问
- android - AdMob Native Advanced 宽度和空白可点击
- python - PonyORM/Postgres 多租户选项
- php - 如何在laravel的产品表字段中插入具有3位唯一ID的类别名称
- python - 使用 Python 的 Openpyxl 进行索引匹配
- c# - 如何“干净地”查询基于另一个类中的值与关联表的对象列表?
- html - 无论选择什么,每次选择都会产生与全局变量相同的值数据
- c# - FOREach循环同时用于两个ArrayList c#
- r - 在图表中添加一条最佳拟合线