【发布时间】:2014-01-06 18:48:25
【问题描述】:
仍在尝试了解多索引选择。构建数据框:
import pandas as pd
from numpy import *
arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'],
['cat', 'cat', 'cat', 'cat', 'dog', 'dog', 'dog', 'dog']]
tuples = zip(*arrays)
index = pd.MultiIndex.from_tuples(tuples, names=['first','second','third'])
data = pd.DataFrame(random.randn(8,3), index=index, columns=['c1','c2','c3'])
>>> data
c1 c2 c3
first second third
bar one cat -0.309651 -0.242866 0.824422
two cat -0.349640 0.873796 -1.879832
baz one cat -0.851390 -1.241419 -0.016495
two cat 0.737211 -0.617967 -2.215459
foo one dog -0.231820 0.140641 -1.619270
two dog -1.363132 -0.929765 -0.005083
qux one dog -1.187903 -0.753883 -0.442464
two dog 0.652967 0.423994 -0.705735
问题 1: 如果我想将“c1”值更改为 c1*10,我可以按原样进行吗?我试过了
data.ix['cat'].c1 = data.ix['cat'].c1*10
# Also tried
data.xs('cat',level='second').c1 = data.xs('cat',level='second').c1*10
两者都不起作用。我得到一个“KeyError”的第一个和
"TypeError: 'instancemethod' object has no attribute 'getitem'" for the second
令人困惑的解决方案
我找到了重新排序索引的解决方案,但这有奇怪的行为(至少对我来说很奇怪)。
d = data.copy()
d.index = d.index.reorder_levels( [2,0,1] )
>>> d
c1 c2 c3
third first second
cat bar one -0.309651 -0.242866 0.824422
two -0.349640 0.873796 -1.879832
baz one -0.851390 -1.241419 -0.016495
two 0.737211 -0.617967 -2.215459
dog foo one -0.231820 0.140641 -1.619270
two -1.363132 -0.929765 -0.005083
qux one -1.187903 -0.753883 -0.442464
two 0.652967 0.423994 -0.705735
# Now perform the operation (use *NaN below to make changes easily distinguished)
d.ix['cat'].c1 = d.ix['cat'].c1*NaN
>>> d
c1 c2 c3
third first second
cat bar one NaN -0.242866 0.824422
two NaN 0.873796 -1.879832
baz one NaN -1.241419 -0.016495
two NaN -0.617967 -2.215459
dog foo one -0.231820 0.140641 -1.619270
two -1.363132 -0.929765 -0.005083
qux one -1.187903 -0.753883 -0.442464
two 0.652967 0.423994 -0.705735
太棒了!那行得通。但是,如果我想让“第二”成为第一个索引呢?
d = data.copy()
d.index = d.index.reorder_levels( [1,0,2] )
>>> d
c1 c2 c3
second first third
one bar cat -0.309651 -0.242866 0.824422
two bar cat -0.349640 0.873796 -1.879832
one baz cat -0.851390 -1.241419 -0.016495
two baz cat 0.737211 -0.617967 -2.215459
one foo dog -0.231820 0.140641 -1.619270
two foo dog -1.363132 -0.929765 -0.005083
one qux dog -1.187903 -0.753883 -0.442464
two qux dog 0.652967 0.423994 -0.705735
# Using the same logic as above...
d.ix['two'].c1 = d.ix['two'].c1*NaN
>>> c1 c2 c3
second first third
one bar cat -0.309651 -0.242866 0.824422
two bar cat -0.349640 0.873796 -1.879832
one baz cat -0.851390 -1.241419 -0.016495
two baz cat 0.737211 -0.617967 -2.215459
one foo dog -0.231820 0.140641 -1.619270
two foo dog -1.363132 -0.929765 -0.005083
one qux dog -1.187903 -0.753883 -0.442464
two qux dog 0.652967 0.423994 -0.705735
没有变化!但这(下)确实有效
# Keeping same data frame from previous example
d.c1.ix['two'] = d.ix['two'].c1*NaN
>>> d
c1 c2 c3
second first third
one bar cat -0.309651 -0.242866 0.824422
two bar cat NaN 0.873796 -1.879832
one baz cat -0.851390 -1.241419 -0.016495
two baz cat NaN -0.617967 -2.215459
one foo dog -0.231820 0.140641 -1.619270
two foo dog NaN -0.929765 -0.005083
one qux dog -1.187903 -0.753883 -0.442464
two qux dog NaN 0.423994 -0.705735
问题 2: 我不明白为什么 d.ix['ID'].c1 vs d.c1.ix['ID'] 的顺序取决于数据框的索引级别的排序方式。这对其他人有意义吗?如果是这样,你能解释一下这里发生了什么吗?任何帮助深表感谢。
【问题讨论】:
-
阅读:pandas.pydata.org/pandas-docs/dev/…。使用
df.loc[row,column] = value确保您设置的是实际对象 -
所以你只想改变一个子框架,例如由某个级别索引的某个列?或所有列
c1? -
只是想换个子帧。
标签: python-2.7 indexing pandas dataframe