Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 修改数据帧中的行子集_Python_Pandas - Fatal编程技术网

Python 修改数据帧中的行子集

Python 修改数据帧中的行子集,python,pandas,Python,Pandas,假设我有一个包含两列a和B的pandas数据框。我想修改这个数据框或创建一个副本,以便每当a为0时,B总是NaN。我将如何实现这一点 我尝试了以下方法 df['A'==0]['B'] = np.nan 及 没有成功。用于基于标签的索引: df.loc[df.A==0, 'B'] = np.nan df.A==0表达式创建一个对行进行索引的布尔序列,“B”选择列。您还可以使用此选项转换列的子集,例如: df.loc[df.A==0, 'B'] = df.loc[df.A==0, 'B'] /

假设我有一个包含两列a和B的pandas数据框。我想修改这个数据框或创建一个副本,以便每当a为0时,B总是NaN。我将如何实现这一点

我尝试了以下方法

df['A'==0]['B'] = np.nan

没有成功。

用于基于标签的索引:

df.loc[df.A==0, 'B'] = np.nan
df.A==0表达式创建一个对行进行索引的布尔序列,“B”选择列。您还可以使用此选项转换列的子集,例如:

df.loc[df.A==0, 'B'] = df.loc[df.A==0, 'B'] / 2
我对pandas的内部结构了解不够,无法确切地知道为什么这样做,但基本问题是,有时索引到数据帧会返回结果的副本,有时会返回原始对象的视图。根据文档,此行为取决于基础numpy行为。我发现在一次操作中访问所有内容比在[1][2]中访问所有内容更有可能用于设置。

来自pandas docs on advanced indexing:

本节将准确解释您需要什么!事实证明,df.loc as.ix已被弃用——正如许多人在下面指出的,它可以用于数据帧的冷切片/切割。和它也可以用来设置东西

df.loc[selection criteria, columns I want] = value
所以Bren的回答是“找到df.A==0的所有地方,选择B列并将其设置为np.nan”,从0.20开始。正确的方法是使用

下面是一个工作示例

>>> 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
>>> 
说明: 如文档中所述,.loc主要基于标签,但也可以与布尔数组一起使用

因此,我们在上面所做的是通过以下方式应用df.loc[行索引,列索引]:

利用loc可以将布尔数组作为掩码的事实,告诉熊猫我们要在行索引中更改哪些行子集 利用事实loc也是基于标签的,使用列索引中的标签“B”选择列 我们可以使用逻辑、条件或任何返回一系列布尔值的操作来构造布尔值数组。在上面的示例中,我们需要任何包含0的行,因此我们可以使用df.a==0,正如您在下面的示例中所看到的,这将返回一系列布尔值

>>> 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
>>> 
然后,我们使用上面的布尔数组来选择和修改必要的行:

>>> df.loc[df.A == 0, 'B'] = np.nan
>>> df
   A   B
0  0 NaN
1  1   0
2  0 NaN

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

要替换多个列,请使用.value转换为numpy数组:


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

安装程序 创建一个包含100000行的两列数据框,其中包含一些零

df = pd.DataFrame(np.random.randint(0,3, (100000,2)), columns=list('ab'))
使用numpy.where快速解决方案 时间安排
Numpy的where大约快4倍

如果您正在寻找一个非常快速的解决方案,请使用Numpy的where,如中所示,我对此很好奇,所以我自己测试了它,使用其他参数时差异更大。Numpy用整数代替0而不是np.nan的速度快了近10倍。我想知道什么需要额外的时间。是否有必要在np.wheredf.a.values==0,np.nan,df.b.values中使用.values?看起来np.wheredf.a==0,np.nan,df.b也有效?是的,不知怎么的,loc[选择标准,我想要的列]完美地印在你的脑海中……这篇文章的第二部分是一个很好的答案,回答了一个甚至没有被问到的问题;-我想知道这是否仍然是规范的熊猫答案,特别是b/c,这是一个明显的干违反,尽管我认为,鉴于熊猫内部的限制,事实上有必要违反干?我可能会更详细地发布这类问题,但我想在我之前看看您是否有一个快速的答案。如何对没有列名的数据帧进行子集划分,如何仅通过索引对df进行子集划分?df.loc[df[0]==0]不工作。。。替代方案是什么?非常感谢。
df.loc[df.A==0, ['B', 'C']] = df.loc[df.A==0, ['B', 'C']].values / 2
df = pd.DataFrame(np.random.randint(0,3, (100000,2)), columns=list('ab'))
df['b'] = np.where(df.a.values == 0, np.nan, df.b.values)
%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)