我正在尝试修改数据框的单行中的两个值。但是,我得到一个例外,我无法解释原因。
In [1]: import numpy as np
In [2]: import pandas as pd
In [3]: df = pd.DataFrame(np.random.rand(2,3), index=['one', 'two'],
columns=list('ABC'))
In [4]: df['Z'] = list(range(len(df.index)))
In [5]: df.head(1)
Out[5]:
A B C Z
one 0.977917 0.734311 0.069476 0
In [6]: df.iloc[0] = dict(B=3.5, Z=10)
/home/rajatgirotra/tools/miniconda2/envs/shriram/lib/python2.7/site-packages/pandas/core/indexing.pyc in _setitem_with_indexer(self,indexer,value) 525 526如果len(标签)!= len(值): - > 527引发ValueError('必须具有相等的len键和值' 528'设置为可迭代时') 529
ValueError:设置时必须具有相等的len键和值 可迭代
这种方式不正确吗?如何轻松修改同一行中的一个或多个单元格值?
答案 0 :(得分:3)
我认为您需要按loc
或iloc
的dict键选择仅列,否则获取NaN
s:
d = dict(B=3.5, Z=10)
df.loc[df.index[0], d.keys()] = pd.Series(d)
print (df)
A B C Z
one 0.062352 3.500000 0.225811 10.0
two 0.655920 0.386443 0.063906 1.0
df.iloc[0, df.columns.get_indexer(d.keys())] = pd.Series(d)
print (df)
A B C Z
one 0.422479 3.500000 0.951087 10.0
two 0.097426 0.702746 0.257591 1.0
df.loc[df.index[0]] = pd.Series(d)
print (df)
A B C Z
one NaN 3.500000 NaN 10.0
two 0.050399 0.917007 0.951725 1.0
df.iloc[0] = pd.Series(d)
print (df)
A B C Z
one NaN 3.500000 NaN 10.0
two 0.5356 0.844221 0.023227 1.0
答案 1 :(得分:3)
@ jezrael的df.iloc[0] = pd.Series(d)
是我的偏好。
但您也可以使用pd.DataFrame.update
并将字典包装在pd.DataFrame
df.update(pd.DataFrame(dict(B=3.5, Z=10), ['one']))
df
A B C Z
one 0.339970 3.500000 0.528206 10.0
two 0.553827 0.117207 0.784605 1.0
虽然我在这里,但这是一种使用pd.DataFrame.set_value
和列表理解的创造性方式。这样做的好处是不需要构建数据帧的开销,并注意dtype
列上保留'Z'
[df.set_value('one', k, v) for k, v in dict(B=3.5, Z=10).items()];
df
A B C Z
one 0.099669 3.500000 0.248170 10
two 0.604340 0.305114 0.897305 1
这并不重要,但这是微小数据样本的时间
%timeit [df.set_value('one', k, v) for k, v in dict(B=3.5, Z=10).items()];
%timeit df.update(pd.DataFrame(dict(B=3.5, Z=10), ['one']))
%timeit df.iloc[0] = pd.Series(dict(B=3.5, Z=10))
100000 loops, best of 3: 5.29 µs per loop
1000 loops, best of 3: 1.51 ms per loop
1000 loops, best of 3: 402 µs per loop