为Pandas DataFrame列的单个行分配值

时间:2014-07-23 23:22:06

标签: python pandas

我正在尝试在Pandas DataFrame中的一行中重新分配值。

import pandas as pd
import numpy as np

这是DataFrame:

test_df = pd.DataFrame({'range_total' : [3000,3000,3000,3000,3000,3000,0,2000,2000,1000,1000,1000,1000,1000,1000],
    'high_boundary' : [6,6,6,6,6,6,7,9,9,15,15,15,15,15,15],
    'dist_num' : [1197, 142, 142, 1197, 159, 159, 0, 1000, 1000, 398, 50, 50, 398, 50, 50],
    'round_num_sum' : [2996, 2996, 2996, 2996, 2996, 2996, 0, 2000, 2000, 996, 996, 996, 996, 996, 996]})

在我的代码中,我为high_boundary的每个值对DataFrame进行了子集,并找到与test_df的最大值对应的dist_num的索引(如果绑定则选择第一个值) )。对于此示例,我将索引设置为:

sub_idx = 0 

我可以使用此(和其他类似版本)代码访问该值:

test_df.ix[(test_df.high_boundary == 6), "dist_num"][sub_idx]

返回:

1197

但是分配新值失败:

test_df.ix[(test_df.high_boundary == 6), "dist_num"][sub_idx] = 42
test_df.ix[(test_df.high_boundary == 6), "dist_num"][sub_idx]

仍然会返回:

1197 

可是:

test_df.ix[(test_df.high_boundary == 6), "dist_num"] = 42
test_df.ix[(test_df.high_boundary == 6), "dist_num"]

返回:

0    42
1    42 
2    42
3    42
4    42
5    42
Name: dist_num, dtype: int64

我感谢任何帮助。这是我的第一篇文章,因为直到现在我总能找到我所需要的东西。我使用的是版本0.14.0。

3 个答案:

答案 0 :(得分:0)

有时您可以获得(部分)原始数据框test_df的副本。

特别是如果您使用[...][...]

选择元素

所以你在副本中更改了一个值,而不是在原始test_df

试试这个例子:

test_df["dist_num"].ix(test_df.high_boundary == 6)[sub_idx] = 0

你应该得到预期的结果。

答案 1 :(得分:0)

过去有过类似的问题。建议你通过

的例子来工作

http://pandas.pydata.org/pandas-docs/stable/indexing.html

特别是该部分 http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy会帮助你。

编辑解释说,如果你使用df [] []构造进行链切片,你经常会切换到第1个系列然后切换到值。 pandas跟踪原始过滤器以允许您回写切片是不可行的。

简短回答尝试使用单个运算符(如“.loc”)来执行您要分配的选择。

答案 2 :(得分:0)

几年后重新访问此代码时,我发现上面发布的解决方案现在提供了一个错误(使用Pandas版本0.20.1和Python 2.7.13): TypeError: 'Series' objects are mutable, thus they cannot be hashed。如果其他人有这个问题,我在下面添加了一个解决方案。

要更新pd.DataFrame子集的单个元素,找到子集中的索引值,然后使用与所需行对应的索引来选择要更新的元素

sub_idx = 0

indices = test_df.loc[test_df.high_boundary == 6,"dist_num"].index
print(test_df.loc[indices[sub_idx],"dist_num"])
# 1197
test_df.loc[indices[sub_idx],"dist_num"] = 0 

print(test_df.loc[indices[sub_idx],"dist_num"])
# 0