假设我有一个带有两列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
'
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_index
在rows
我们可以使用逻辑,条件或任何返回一系列布尔值的操作来构造布尔数组.在上面的例子中,我们想要任何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)
有关更多信息,请在此处查看高级索引文档.
要大幅提高速度,请使用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倍
要使用以下方法替换多个列转换为 numpy 数组.values
:
df.loc[df.A==0, ['B', 'C']] = df.loc[df.A==0, ['B', 'C']].values / 2
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
114348 次 |
最近记录: |