以下是我的问题的最低工作示例:
import pandas as pd
columns = pd.MultiIndex.from_product([['a', 'b', 'c'], range(2)])
a = pd.DataFrame(0.0, index=range(3),columns=columns, dtype='float')
b = pd.Series([13.0, 15.0])
a.loc[1,'b'] = b # this line results in NaNs
a.loc[1,'b'] = b.values # this yields correct behavior
为什么第一个作业不正确?两个系列似乎都有相同的索引,所以我认为它应该产生正确的结果。
我正在使用pandas 0.17.0。
答案 0 :(得分:4)
写作时
a.loc[1,'b'] = b
和b
是一个系列,b
的索引必须与a.loc[1,'b']
生成的索引器完全匹配才能将b
中的值复制到{ {1}}。但事实证明,当a
为a.columns
时,the indexer for a.loc[1,'b']
为:
MultiIndex
而(Pdb) p new_ix
Index([(u'b', 0), (u'b', 1)], dtype='object')
的索引是
b
它们不匹配,因此
(Pdb) p ser.index
Int64Index([0, 1], dtype='int64')
由于值未对齐,the code branch you fall into会分配
(Pdb) p ser.index.equals(new_ix)
False
我通过在代码中添加(Pdb) p ser.reindex(new_ix).values
array([ nan, nan])
找到了这个:
pdb.set_trace()
然后在“高级别”单步执行并找到the problem occurs in
import pandas as pd
columns = pd.MultiIndex.from_product([['a', 'b', 'c'], range(2)])
a = pd.DataFrame(0.0, index=range(3),columns=columns, dtype='float')
b = pd.Series([13.0, 15.0])
import pdb
pdb.set_trace()
a.loc[1,'b'] = b # this line results in NaNs
a.loc[1,'b'] = b.values # this yields correct behavior
然后再次踩过它(用一把更细的梳子),从一个叫做 if isinstance(value, ABCSeries):
value = self._align_series(indexer, value)
的线开始有一个断点。
请注意,如果您将self._align_series(indexer, value)
的索引更改为MultiIndex:
b
然后
b = pd.Series([13.0, 15.0], index=pd.MultiIndex.from_product([['b'], [0,1]]))
产量
import pandas as pd
columns = pd.MultiIndex.from_product([['a', 'b', 'c'], range(2)])
a = pd.DataFrame(0.0, index=range(3),columns=columns, dtype='float')
b = pd.Series([13.0, 15.0], index=pd.MultiIndex.from_product([['b'], [0,1]]))
a.loc[1,'b'] = b
print(a)
答案 1 :(得分:1)
您可以直接将b
分配到a
中的列,因为b
不是多索引系列。更改b
会使其有效:
columns = pd.MultiIndex.from_product([['a', 'b', 'c'], range(2)])
a = pd.DataFrame(0.0, index=range(3),columns=columns, dtype='float')
index = pd.MultiIndex.from_product([['b'], range(2)])
b = pd.Series([13.0, 15.0], index=index)
a.loc[1,'b'] = b
print(a)
产量
a b c
0 1 0 1 0 1
0 0 0 0 0 0 0
1 0 0 13 15 0 0
2 0 0 0 0 0 0
使用b.values
的另一种情况可能有效,因为Pandas会在b
中获取面值,并尝试对提供的值进行最合理的分配。