如何将MultiIndex级别强制为dtype

时间:2018-08-26 16:00:37

标签: python pandas

我使用combine_first来基于两个键组合两个DataFrame,目标是将df1中不包含的df2索引附加到结果中,并用的值覆盖两个中包含的索引df2。

示例df1:

df1 = pd.DataFrame({
    "key1": ["A", "A", "A", "B", "B", "C", "C"],
    "id": ["a1", "a2", "a3", 1, 2, "c1", "c2"],
    "data1": [pd.np.random.randint(5) for i in range(7)],
    "data2": [pd.np.random.randint(1000) for i in range(7)]
})

示例df2:

df2 = pd.DataFrame({
    "key1": ["B", "B", "B"],
    "id": [2, 3, 4],
    "data1": [pd.np.random.randint(5) for i in range(3)],
    "data2": [pd.np.random.randint(1000) for i in range(3)]
})

df1.set_index(["key1", "id"]).combine_first(df2.set_index(["key1", "id"]))给出了预期的结果:

         data1  data2
key1 id              
A    a1    0.0  588.0
     a2    2.0  709.0
     a3    3.0  877.0
B    1     3.0  468.0
     2     0.0  612.0
     3     2.0  139.0
     4     3.0  154.0
C    c1    4.0  855.0
     c2    4.0  564.0

但是,将结果存储为csv后,再次加载并运行相同的命令后,出现以下错误:

TypeError: '<' not supported between instances of 'str' and 'int'

但仅对于idint的df2。当id包含字符时,它可以正常工作。

我在Pandas文档中发现了this

  

不同的索引操作可能会更改a的dtype   系列。

这将解释为什么如果我在设置索引和合并之前将df2.id的dtype更改为object,为什么问题仍然存在。如何专门设置MultiIndex级别的dtype以便组合起作用?


编辑 为了进一步说明问题,

df = df1.set_index(["key1", "id"]).combine_first(df2.set_index(["key1", "id"]))
df.to_csv("tests/combtest2.csv", sep=";")
df_loaded = pd.read_csv("tests/combtest2.csv", sep=";", index_col=["key1", "id"])

看起来不错:

         data1  data2
key1 id              
A    a1    0.0  588.0
     a2    2.0  709.0
     a3    3.0  877.0
B    1     3.0  468.0
     2     0.0  612.0
     3     2.0  139.0
     4     3.0  154.0
C    c1    4.0  855.0
     c2    4.0  564.0

但是df_loaded.combine_first(df2.set_index(["key1", "id"]))会导致:

         data1  data2
key1 id              
A    a1    0.0  588.0
     a2    2.0  709.0
     a3    3.0  877.0
B    1     3.0  468.0
     2     0.0  612.0
     3     2.0  139.0
     4     3.0  154.0
C    c1    4.0  855.0
     c2    4.0  564.0
B    2     2.0  317.0
     3     2.0  139.0
     4     3.0  154.0

1 个答案:

答案 0 :(得分:1)

在合并之前,应将id列转换为str,而不是object

这将起作用:

df2.id = df2.id.astype(str)
df_loaded.combine_first(df2.set_index(["key1", "id"]))