2017-08-24 51 views
2

我試圖將一個系列設置爲另一個系列,處於多索引值。沒有複雜的黑客攻擊,我無法在熊貓中找到辦法。在一個熊貓MultiIndex系列中設置值

我原來的系列:

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 

我想不出一個優雅在熊貓中這樣做的方法。所有我已經能夠做的就是下面的技巧:

# 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)     

這將產生所需的輸出。

問:是否有一個簡單,優雅的方式來做到這一點在熊貓?

+0

你的符號是有點混亂,因爲'df'不是數據框... – C8H10N4O2

+0

相關:https://stackoverflow.com/questions/18062135/combining-two-series-into-a-dataframe-熊貓? – C8H10N4O2

+0

@ C8H10N4O2被抓住了,修好了 –

回答

3

選項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 
+0

哦!我知道這有一個'keys'參數的用法。這很聰明。 –

+0

謝謝親愛的先生( - : – piRSquared

+0

)我相信我應該在24小時內得到我的銀色熊貓徽章,感謝所有的支持,以及很久以前的支持,不能忘記它 –

4

你可以嘗試使用pd.concat

In [370]: pd.concat([df, new_data.to_frame().assign(_='three').set_index(['_', new_data.index]).iloc[:, 0]]) 
Out[370]: 
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 
+0

@ C8H10N4O2'df'具有誤導性。 –

+0

@ C8H10N4O2祝你好運,我正在尋找一個比這更好的解決方案,但似乎無法找到它。 –

2

如果你有相當的多指數new_data開始時,你可以直接與pd.concat串聯的Series ES沒有強迫到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 
+0

看起來不錯,雖然也許OP想要一些不涉及多重索引開始的東西,儘管我不確定這是可能的。 –