2016-08-24 117 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了解了很多。谢谢。 –