Python 使用布尔子索引更新数据帧

Python 使用布尔子索引更新数据帧,python,pandas,Python,Pandas,假设我有一个数据帧,我想用1替换任何高于1的条目。数据帧有多种数据类型(字符串、数字和日期),因此: 返回: AttributeError: 'float' object has no attribute 'view' 如果我这样做: df[cols].gt(1.2) # where cols are a specific subset of df.columns 我得到原始数据帧的布尔子集,其中条目高于1.2。但是,如果我尝试使用此结果更新我的原始数据帧,它将不起作用: df.ix[df[

假设我有一个数据帧,我想用1替换任何高于1的条目。数据帧有多种数据类型(字符串、数字和日期),因此:

返回:

AttributeError: 'float' object has no attribute 'view'
如果我这样做:

df[cols].gt(1.2) # where cols are a specific subset of df.columns
我得到原始数据帧的布尔子集,其中条目高于
1.2
。但是,如果我尝试使用此结果更新我的原始数据帧,它将不起作用:

df.ix[df[cols].gt(1.2), cols] = 1 # This doesn't update the dataframe the right way
如何更新原始数据帧

注意:这都是
0.13.1

> df.dtypes
year                            int64
week                            int64
item_name                      object
item_uid                       object
algorithm                      object
item start                    float64
item 1/4                      float64
item 1/2                      float64
item 3/4                      float64
item complete                 float64
daily data                    float64
date                   datetime64[ns]
weekly rate                   float64
dtype: object

你可以一直这样做

df.update((df[cols] > 1.2).replace((True, False), (1, np.nan))

另一个选项是使用
\u get\u numeric\u data()
方法。我建议不要依赖内部方法,但在这种情况下,它很有用:

In [67]: df = DataFrame(randn(10, 3))

In [68]: df['b'] = 'c'

In [69]: df['a'] = 'd'

In [70]: df['date'] = pd.date_range('20130101', periods=10)

In [71]: df
Out[71]:
        0       1       2  b  a       date
0 -0.2094 -1.6014  0.4309  c  d 2013-01-01
1  0.5508  0.9743 -0.1097  c  d 2013-01-02
2  0.8589  0.2062 -0.9720  c  d 2013-01-03
3  0.9868 -0.9927 -1.2546  c  d 2013-01-04
4  0.1206  1.4992 -3.1880  c  d 2013-01-05
5 -1.1514 -0.4342  0.4475  c  d 2013-01-06
6  0.3164 -1.3131  0.1723  c  d 2013-01-07
7 -0.2959 -1.2914 -0.6876  c  d 2013-01-08
8 -0.8382  0.1901  0.9898  c  d 2013-01-09
9  0.5659 -1.6537 -0.6423  c  d 2013-01-10

[10 rows x 6 columns]

In [72]: df.dtypes
Out[72]:
0              float64
1              float64
2              float64
b               object
a               object
date    datetime64[ns]
dtype: object

In [73]: num_data = df._get_numeric_data()

In [74]: df.loc[num_data > 1.2, num_data.columns]
Out[74]:
        0       1       2
0 -0.2094 -1.6014  0.4309
1  0.5508  0.9743 -0.1097
2  0.8589  0.2062 -0.9720

[3 rows x 3 columns]

In [75]: df.loc[num_data > 1.2, num_data.columns] = 1

In [76]: df
Out[76]:
        0       1       2  b  a       date
0  1.0000  1.0000  1.0000  c  d 2013-01-01
1  1.0000  1.0000  1.0000  c  d 2013-01-02
2  1.0000  1.0000  1.0000  c  d 2013-01-03
3  0.9868 -0.9927 -1.2546  c  d 2013-01-04
4  0.1206  1.4992 -3.1880  c  d 2013-01-05
5 -1.1514 -0.4342  0.4475  c  d 2013-01-06
6  0.3164 -1.3131  0.1723  c  d 2013-01-07
7 -0.2959 -1.2914 -0.6876  c  d 2013-01-08
8 -0.8382  0.1901  0.9898  c  d 2013-01-09
9  0.5659 -1.6537 -0.6423  c  d 2013-01-10

[10 rows x 6 columns]

不能对
DataFrame.update()
的结果调用
replace
方法,因为它返回
None
并且
None
只有dunder方法。我认为这是一个错误,因为如果与
数组([1.2])比较
相反,您会得到预期的结果。感谢@PhillipCloud提供使用
数组([1.2])
的可能性。如果我尝试:
df[df.gt(np.array([1.2])]]=1
我得到:
TypeError:无法在混合类型框架上进行布尔设置
。您仍然需要选择数字列。谢谢。我可以运行您的示例,但此解决方案在我的数据帧上失败。我正在调查原因,但是调用
df.\u get\u numeric\u data
返回:
。虽然它不会抛出任何异常。@acushner的答案是我的情况下唯一有效的答案。我会尝试发布一些数据,但这真的很奇怪。你有没有打开IPython自动重新加载?当我在编辑一些代码后重新运行它时,有时会出现奇怪的错误。是的。我不知道这是否是问题所在。我会试着把它关掉。
In [67]: df = DataFrame(randn(10, 3))

In [68]: df['b'] = 'c'

In [69]: df['a'] = 'd'

In [70]: df['date'] = pd.date_range('20130101', periods=10)

In [71]: df
Out[71]:
        0       1       2  b  a       date
0 -0.2094 -1.6014  0.4309  c  d 2013-01-01
1  0.5508  0.9743 -0.1097  c  d 2013-01-02
2  0.8589  0.2062 -0.9720  c  d 2013-01-03
3  0.9868 -0.9927 -1.2546  c  d 2013-01-04
4  0.1206  1.4992 -3.1880  c  d 2013-01-05
5 -1.1514 -0.4342  0.4475  c  d 2013-01-06
6  0.3164 -1.3131  0.1723  c  d 2013-01-07
7 -0.2959 -1.2914 -0.6876  c  d 2013-01-08
8 -0.8382  0.1901  0.9898  c  d 2013-01-09
9  0.5659 -1.6537 -0.6423  c  d 2013-01-10

[10 rows x 6 columns]

In [72]: df.dtypes
Out[72]:
0              float64
1              float64
2              float64
b               object
a               object
date    datetime64[ns]
dtype: object

In [73]: num_data = df._get_numeric_data()

In [74]: df.loc[num_data > 1.2, num_data.columns]
Out[74]:
        0       1       2
0 -0.2094 -1.6014  0.4309
1  0.5508  0.9743 -0.1097
2  0.8589  0.2062 -0.9720

[3 rows x 3 columns]

In [75]: df.loc[num_data > 1.2, num_data.columns] = 1

In [76]: df
Out[76]:
        0       1       2  b  a       date
0  1.0000  1.0000  1.0000  c  d 2013-01-01
1  1.0000  1.0000  1.0000  c  d 2013-01-02
2  1.0000  1.0000  1.0000  c  d 2013-01-03
3  0.9868 -0.9927 -1.2546  c  d 2013-01-04
4  0.1206  1.4992 -3.1880  c  d 2013-01-05
5 -1.1514 -0.4342  0.4475  c  d 2013-01-06
6  0.3164 -1.3131  0.1723  c  d 2013-01-07
7 -0.2959 -1.2914 -0.6876  c  d 2013-01-08
8 -0.8382  0.1901  0.9898  c  d 2013-01-09
9  0.5659 -1.6537 -0.6423  c  d 2013-01-10

[10 rows x 6 columns]