在 pandas MultiIndex 系列中设置值
Posted
技术标签:
【中文标题】在 pandas MultiIndex 系列中设置值【英文标题】:Setting values in a pandas MultiIndex series 【发布时间】:2018-02-02 07:15:17 【问题描述】:我正在尝试以多索引值将一个系列设置为另一个系列。如果没有复杂的 hack,我无法在 Pandas 中找到一种方法。
我的原创系列:
one 1 0.522764
3 0.362663
7 0.963108
two 2 0.717855
4 0.004645
5 0.077471
我要连接的数据,级别为three
:
2 0.8
7 0.9
8 0.7
想要的输出:
one 1 0.522764
3 0.362663
7 0.963108
two 2 0.717855
4 0.004645
5 0.077471
three 2 0.800000
7 0.900000
8 0.700000
我无法在 pandas 中找到一种优雅的方式来做到这一点。我所能做的就是以下黑客攻击:
# imports
import numpy as np
import pandas as pd
# to replicate the Series:
np.arrays = [['one','one','one','two','two','two'],[1,3,7,2,4,5]]
my_series = pd.Series([np.random.random() for i in range(6)],
index=pd.MultiIndex.from_tuples(list(zip(*np.arrays))))
# the new data I need to add:
new_data = pd.Series(1: .9, 2: .7, 3: .8)
这是我目前的解决方法:
# rename the index so that I can call it later
new_data.index.name = 'level_1'
# turn it into temporary a dataframe so that I can add a new column
temp = pd.DataFrame(new_data)
# create a new column with the desired name for first index level
temp['level_0'] = 'three'
# reset index, set the new index, turn into Series again
temp = temp.reset_index().set_index(['level_0', 'level_1'])[0]
# append it to the larger dataframe
my_series = my_series.append(temp)
这会产生所需的输出。
问题:在 Pandas 中是否有一种简单、优雅的方式来做到这一点?
【问题讨论】:
您的符号有点混乱,因为df
不是 DataFrame...
相关:***.com/questions/18062135/…?
@C8H10N4O2 抓得好,修好了
我们的回答有帮助吗?
【参考方案1】:
选项 1
pd.concat
是使用keys
参数添加索引或列级别的便捷方式。将此与第二个 pd.concat
结合起来完成工作。
pd.concat([my_series, pd.concat([new_data], keys=['Three'])])
one 1 0.943246
3 0.412200
7 0.379641
two 2 0.883960
4 0.182983
5 0.773227
Three 1 0.900000
2 0.700000
3 0.800000
dtype: float64
选项 2
或者我们可以在向index
参数中插入一个附加数组的同时构造一个新系列。再次使用pd.concat
进行组合。 注意我本可以使用pd.MultiIndex.from_arrays
,但只需将数组直接传递给index
参数,就可以简化语法。
pd.concat([
my_series,
pd.Series(new_data.values, [['Three'] * new_data.size, new_data.index])
])
one 1 0.943246
3 0.412200
7 0.379641
two 2 0.883960
4 0.182983
5 0.773227
Three 1 0.900000
2 0.700000
3 0.800000
dtype: float64
选项 3
用多索引重建系列的另一种方法。这个使用pd.MultiIndex.from_product
。
pd.concat([
my_series,
pd.Series(new_data.values, pd.MultiIndex.from_product([['Three'], new_data.index]))
])
one 1 0.943246
3 0.412200
7 0.379641
two 2 0.883960
4 0.182983
5 0.773227
Three 1 0.900000
2 0.700000
3 0.800000
dtype: float64
【讨论】:
哦!我知道keys
参数是有用的。这很聪明。
我相信我应该会在接下来的 24 小时内拿到我的银色熊猫徽章。感谢所有的支持和很久以前的鼓舞人心的谈话。忘不了。【参考方案2】:
你可以试试pd.concat
:
u = (new_data.to_frame()
.assign(_='three')
.set_index(['_', new_data.index])[0])
pd.concat([df, u])
one 1 0.618472
3 0.026207
7 0.766849
two 2 0.651633
4 0.282038
5 0.160714
three 1 0.900000
2 0.700000
3 0.800000
dtype: float64
【讨论】:
@C8H10N4O2df
具有误导性。
@C8H10N4O2 祝你好运,我自己也在寻找比这更好的解决方案,但似乎找不到。【参考方案3】:
如果您从 new_data
的等效多索引开始,则可以将 Series
es 直接与 pd.concat
连接,而无需强制转换为 DataFrame
并返回,如下所示:
new_series = pd.Series([0.8,0.9,0.7],
index=pd.MultiIndex.from_tuples([('three',x) for x in range(1,4)])
)
pd.concat([my_series,new_series]) #note OP changed name of orig series from df to my_series
#==============================================================================
# one 1 0.236158
# 3 0.699102
# 7 0.421937
# two 2 0.887081
# 4 0.520304
# 5 0.211461
# three 1 0.800000
# 2 0.900000
# 3 0.700000
# dtype: float64
#==============================================================================
type(pd.concat([my_series,new_series])) # pandas.core.series.Series
【讨论】:
看起来不错,虽然也许 OP 想要一些不涉及声明多索引的东西,尽管我不确定这是否可能。以上是关于在 pandas MultiIndex 系列中设置值的主要内容,如果未能解决你的问题,请参考以下文章
将 pandas 系列的 numpy 矩阵转换为 Multiindex 系列
concat和sum multiindex pandas系列
Pandas - 将 DataFrame 值除以 MultiIndex DataFrame 中的系列