修改pandas数据帧中的行子集

Art*_* B. 126 python pandas

假设我有一个带有两列A和B的pandas DataFrame.我想修改这个DataFrame(或者创建一个副本),这样只要A为0,B总是NaN.我将如何实现?

我尝试了以下内容

df['A'==0]['B'] = np.nan
Run Code Online (Sandbox Code Playgroud)

df['A'==0]['B'].values.fill(np.nan)
Run Code Online (Sandbox Code Playgroud)

没有成功.

Bre*_*arn 221

使用.loc基于标签索引:

df.loc[df.A==0, 'B'] = np.nan
Run Code Online (Sandbox Code Playgroud)

df.A==0表达式创建一个布尔序列,用于索引行,'B'选择列.您还可以使用它来转换列的子集,例如:

df.loc[df.A==0, 'B'] = df.loc[df.A==0, 'B'] / 2
Run Code Online (Sandbox Code Playgroud)

我对pandas内部结构知之甚少并不知道为什么可行,但基本问题是有时索引到DataFrame会返回结果的副本,有时它会返回原始对象的视图.根据此处的文档,此行为取决于潜在的numpy行为.我发现在一次操作中访问所有内容(而不是[one] [two])更有可能用于设置.


bad*_*ley 84

是关于高级索引的pandas docs:

该部分将准确解释您的需求!事实证明df.loc(因为.ix已被弃用 - 正如下面许多人所指出的那样)可以用于数据帧的冷切片/切割.和.它也可以用来设置东西.

df.loc[selection criteria, columns I want] = value
Run Code Online (Sandbox Code Playgroud)

所以Bren的回答是说'找到我所有的地方df.A == 0,选择列B并将其设置为np.nan'

  • 你让我今天一整天都感觉很好。明确的解释。 (2认同)
  • 是的,不知何故,`loc[selection criteria, columns I want]` 完全符合你的想法...... (2认同)

Moh*_*OUI 25

从pandas 0.20 ix开始不推荐使用.正确的方法是使用.loc

这是一个有效的例子

>>> import pandas as pd 
>>> import numpy as np 
>>> df = pd.DataFrame({"A":[0,1,0], "B":[2,0,5]}, columns=list('AB'))
>>> df.loc[df.A == 0, 'B'] = np.nan
>>> df
   A   B
0  0 NaN
1  1   0
2  0 NaN
>>> 
Run Code Online (Sandbox Code Playgroud)

说明:

如在doc解释这里,df.loc[row_index, column_index] 主要是基于标签,但也可以用布尔阵列使用.

那么,我们上面所做的是申请loc:

  • 利用row_index可以将布尔数组作为掩码的事实来告诉pandas我们想要更改哪些行的子集loc
  • 利用这样的事实'B'也是基于标签来选择使用标签列column_indexrows

我们可以使用逻辑,条件或任何返回一系列布尔值的操作来构造布尔数组.在上面的例子中,我们想要任何0包含a df.A == 0的东西,我们可以使用它.loc,正如你在下面的例子中看到的那样,它返回一系列布尔值.

>>> df = pd.DataFrame({"A":[0,1,0], "B":[2,0,5]}, columns=list('AB'))
>>> df 
   A  B
0  0  2
1  1  0
2  0  5
>>> df.A == 0 
0     True
1    False
2     True
Name: A, dtype: bool
>>> 
Run Code Online (Sandbox Code Playgroud)

然后,我们使用上面的布尔数组来选择和修改必要的行:

>>> df.loc[df.A == 0, 'B'] = np.nan
>>> df
   A   B
0  0 NaN
1  1   0
2  0 NaN
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请在此处查看高级索引文档.


Ted*_*rou 8

要大幅提高速度,请使用NumPy的where函数。

设定

创建一个两列DataFrame,其中包含100,000行,其中一些零。

df = pd.DataFrame(np.random.randint(0,3, (100000,2)), columns=list('ab'))
Run Code Online (Sandbox Code Playgroud)

快速解决方案 numpy.where

df['b'] = np.where(df.a.values == 0, np.nan, df.b.values)
Run Code Online (Sandbox Code Playgroud)

时机

%timeit df['b'] = np.where(df.a.values == 0, np.nan, df.b.values)
685 µs ± 6.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit df.loc[df['a'] == 0, 'b'] = np.nan
3.11 ms ± 17.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Run Code Online (Sandbox Code Playgroud)

Numpy的where速度大约快4倍


Adr*_*aud 5

要使用以下方法替换多个列转换为 numpy 数组.values

df.loc[df.A==0, ['B', 'C']] = df.loc[df.A==0, ['B', 'C']].values / 2
Run Code Online (Sandbox Code Playgroud)