Python 数据帧二级索引和重新分配值的子集
这可能是一个由两部分组成的问题,但我正在寻找对由二级索引标识的记录子集进行重新缩放(或执行任何操作)的最佳方法 例如,假设我有以下数据帧:Python 数据帧二级索引和重新分配值的子集,python,pandas,Python,Pandas,这可能是一个由两部分组成的问题,但我正在寻找对由二级索引标识的记录子集进行重新缩放(或执行任何操作)的最佳方法 例如,假设我有以下数据帧: >>> df=pd.DataFrame(data=[[1,2,3],[.4,.5,.6],[7,8,9],[.10,.11,.12]], index=pd.MultiIndex.from_tuples([(1,'a'), (1,'b'), (2,'a'), (2,'b')]), columns=['Var1','Var2','Var3'])
>>> df=pd.DataFrame(data=[[1,2,3],[.4,.5,.6],[7,8,9],[.10,.11,.12]], index=pd.MultiIndex.from_tuples([(1,'a'), (1,'b'), (2,'a'), (2,'b')]), columns=['Var1','Var2','Var3'])
>>> df.index.names=['Number','Letter']
>>> print df
Var1 Var2 Var3
Number Letter
1 a 1.0 2.00 3.00
b 0.4 0.50 0.60
2 a 7.0 8.00 9.00
b 0.1 0.11 0.12
我希望字母“b”标识的两个记录将所有3个变量乘以10
我正在努力解决的第一个问题是如何在多索引的第二个索引上进行选择。我可以通过以下草率的方法来实现这一点,但我可以想象有一种更干净的方法:
>>> df=df.reset_index().set_index(['Letter','Number'])
>>> Records=df.loc['b']
>>> print Records
Var1 Var2 Var3
Number
1 0.4 0.50 0.60
2 0.1 0.11 0.12
关于第二个索引子集的更好方法,有什么建议吗
然后我可以重新缩放它们:
>>> print Records*10
Var1 Var2 Var3
Number
1 4 5 6
2 10 11 12
但是,如何用这些新重新缩放的值替换原始值?如果第二个索引级别为
'b'
,则将值缩放10倍:
In [82]:
print pd.DataFrame(data=df.values*np.where(df.index.get_level_values(1) == 'a', 1, 10).reshape((-1,1)),
index=df.index)
0 1 2
Number Letter
1 a 1 2.0 3.0
b 4 5.0 6.0
2 a 7 8.0 9.0
b 1 1.1 1.2
或者:
In [94]:
print (df.T * np.where(df.index.get_level_values(1) == 'a', 1, 10)).T
Var1 Var2 Var3
Number Letter
1 a 1 2.0 3.0
b 4 5.0 6.0
2 a 7 8.0 9.0
b 1 1.1 1.2
我将通过unstack使多索引级别成为第一级,然后对其进行切片:
In [72]: df=pd.DataFrame(data=[[1,2,3],[.4,.5,.6],[7,8,9],[.10,.11,.12]], index=pd.MultiIndex.from_tuples([(1,'a'), (1,'b'), (2,'a'), (2,'b')]), columns=['Var1','Var2','Var3'])
In [73]: df
Out[73]:
Var1 Var2 Var3
1 a 1.0 2.00 3.00
b 0.4 0.50 0.60
2 a 7.0 8.00 9.00
b 0.1 0.11 0.12
In [89]: df1 = df.unstack(-2) # the same as level=0
In [90]: df1
Out[90]:
Var1 Var2 Var3
1 2 1 2 1 2
a 1.0 7.0 2.0 8.00 3.0 9.00
b 0.4 0.1 0.5 0.11 0.6 0.12
In [91]: df1.loc['a']*=10
In [92]: df1
Out[92]:
Var1 Var2 Var3
1 2 1 2 1 2
a 10.0 70.0 20.0 80.00 30.0 90.00
b 0.4 0.1 0.5 0.11 0.6 0.12
df = df1.stack().swaplevel(0,1) # return back to the multi-index
使用Pandas,您可以通过以下任一方式访问多索引中的第二级:
df.loc[df.index.isin("b", level="Letter")]
Var1 Var2 Var3
Number Letter
1 b 0.4 0.50 0.60
2 b 0.1 0.11 0.12
或
它不是完全相同的输出,只有第一个版本允许您更改值(感谢loc
以及您保留所有索引值的事实):
这样,您还可以轻松访问给定的列,也可以对其进行修改:
df.loc[df.index.isin("b", level="Letter"), "Var3"] = "Foo"
df
Var1 Var2 Var3
Number Letter
1 a 1 2.0 3
b 4 5.0 Foo
2 a 7 8.0 9
b 1 1.1 Foo
如果您喜欢优雅的方式,希望这对您有所帮助:
df.loc[(slice(None), 'b'), :]
请参阅更多:
df1.stack().swaplevel(0,1)
?是的,这是选项。补充我的答案。谢谢
df.loc[df.index.isin("b", level="Letter"), "Var3"] = "Foo"
df
Var1 Var2 Var3
Number Letter
1 a 1 2.0 3
b 4 5.0 Foo
2 a 7 8.0 9
b 1 1.1 Foo
df.loc[(slice(None), 'b'), :]