2016-08-24 185 views
1

我相信我最終會尋找一種方法來更改數據幀索引的dtype。請允許我解釋:無法合併multiindexed熊貓數據框

每個df在(相同的)四個級別上是多索引的。一個級別由整數,整數和字母(如D8)混合標籤和只是字母組成。

但是,對於df1,索引標籤內的整數由引號包圍,而對於df2,相同的整數標籤不含任何引號;即,

df1.index.levels[1] 
Index(['Z5', '02', '1C', '26', '2G', '2S', '30', '46', '48', '5M', 'CSA', etc...'],  dtype='object', name='BMDIV') 

df2.index.levels[1] 
Index([ 26, 30, 46, 48, 72, '1C', '5M', '7D', '7Y', '8F', 
     '8J', 'AN', 'AS', 'C3', 'CA', etc. 
     dtype='object', name='BMDIV') 

當我嘗試合併這些表

df_merge = pd.merge(df1, df2, how='left', left_index=True, right_index=True) 

我得到:

TypeError: type object argument after * must be a sequence, not map

有沒有辦法改變,例如,標籤的DF2類型,這樣數字是用引號引起的,因此可能與df1中的相應標籤相匹配?改變電平值

+0

你可能要考慮解決這一問題,當您第一次創建這些DataFrames,而不是在合併之前。看看'df1',看起來你有零填充整數字符串,例如''02''。如果它在'df2'中被轉換爲一個正則整數,它就是'2',並且將它轉換爲一個字符串不會給零填充,並且在''02'和''2之間不會發生合併「'。當您轉換爲字符串時,您可以添加零填充單個字符的附加步驟,但似乎最好是在初始化時獲取正確的dtype。 – root

+0

絕對好的做法@root –

回答

1

一種方法是建立一個新的多指標,並將其重新分配給df.index

import pandas as pd 

df = pd.DataFrame(
    {'index':[ 26, 30, 46, 48, 72, '1C', '5M', '7D', '7Y', 
       '8F', '8J', 'AN', 'AS', 'C3', 'CA'], 
    'foo':1, 'bar':2}) 
df = df.set_index(['index', 'foo']) 
level_values = [df.index.get_level_values(i) for i in range(index.nlevels)] 
level_values[0] = level_values[0].astype(str) 
df.index = pd.MultiIndex.from_arrays(level_values) 

使電平值的字符串:

In [53]: df.index.levels[0] 
Out[56]: 
Index(['1C', '26', '30', '46', '48', '5M', '72', '7D', '7Y', '8F', '8J', 'AN', 
     'AS', 'C3', 'CA'], 
     dtype='object', name='index') 

或者,你可以通過使用reset_indexset_value避免有點低級混亂:

import pandas as pd 

df = pd.DataFrame(
    {'index':[ 26, 30, 46, 48, 72, '1C', '5M', '7D', '7Y', 
       '8F', '8J', 'AN', 'AS', 'C3', 'CA'], 
    'foo':1, 'bar':2}) 
df = df.set_index(['index', 'foo']) 

df = df.reset_index('index') 
df['index'] = df['index'].astype(str) 
df = df.set_index('index', append=True) 
df = df.swaplevel(0, 1, axis=0) 

這又產生字符串值的指數水平值:

In [67]: df.index.levels[0] 
Out[67]: 
Index(['1C', '26', '30', '46', '48', '5M', '72', '7D', '7Y', '8F', '8J', 'AN', 
     'AS', 'C3', 'CA'], 
     dtype='object', name='index') 

這兩個選項中,using_MultiIndex更快:

N = 1000 
def make_df(N): 
    df = pd.DataFrame(
     {'index': np.random.choice(np.array(
      [26, 30, 46, 48, 72, '1C', '5M', '7D', '7Y', 
      '8F', '8J', 'AN', 'AS', 'C3', 'CA'], dtype='O'), size=N), 
     'foo':1, 'bar':2}) 
    df = df.set_index(['index', 'foo']) 
    return df 

def using_MultiIndex(df): 
    level_values = [df.index.get_level_values(i) for i in range(index.nlevels)] 
    level_values[0] = level_values[0].astype(str) 
    df.index = pd.MultiIndex.from_arrays(level_values) 
    return df 

def using_reset_index(df): 
    df = df.reset_index('index') 
    df['index'] = df['index'].astype(str) 
    df = df.set_index('index', append=True) 
    df = df.swaplevel(0, 1, axis=0) 
    return df 


In [81]: %%timeit df = make_df(1000) 
    ....: using_MultiIndex(df) 
    ....: 
1000 loops, best of 3: 693 µs per loop 

In [82]: %%timeit df = make_df(1000) 
    ....: using_reset_index(df) 
    ....: 
100 loops, best of 3: 2.09 ms per loop 
+0

我從你的回答@unutbu瞭解了很多。謝謝。 –