python - Pandas 'Int64' 类型合并后转换为 'object' 类型

标签 python pandas dataframe

我在使用 Int64 时注意到以下行为.有没有办法避免类型转换并保留 Int64输入后合并?

df1 = pd.DataFrame(data={'col1': [1, 2, 3, 4, 5], 'col2': [10, 11, 12, 13, 14]}, dtype=pd.Int64Dtype())
df2 = pd.DataFrame(data={'col1': [1, 2, 3], 'col2': [10, 11, 12]}, dtype=pd.Int64Dtype())
df = df2.merge(df1, how='outer', indicator=True, suffixes=('_x', ''))

df1.dtypes
Out[8]: 
col1    Int64
col2    Int64
dtype: object

df2.dtypes
Out[9]: 
col1    Int64
col2    Int64
dtype: object

df.dtypes
Out[10]: 
col1        object
col2        object
_merge    category
dtype: object

我应该澄清一下,我正在寻找一个不涉及明确执行以下操作的答案:
for k, v in df1.dtypes.to_dict().items():
    df[k] = df[k].astype(v)

最佳答案

它来自需要重新索引 df2(基本数据帧),需要重新索引以匹配 df1(合并数据帧)。它可能应该按照您的预期运行,但是使用 pandas Int64Dtype 类型而不是 python int 类型是一个边缘情况。
在执行合并时,这种重新索引被称为:

> /home/tron/.local/lib/python3.7/site-packages/pandas/core/reshape/merge.py(840)_maybe_add_join_keys()
    838                     key_col = rvals
    839                 else:
--> 840                     key_col = Index(lvals).where(~mask, rvals)
    841 
    842                 if result._is_label_reference(name):
然后调用这个数组 dtype。
> /home/tron/.local/lib/python3.7/site-packages/pandas/core/indexes/base.py(359)__new__()
    357                 data = ea_cls._from_sequence(data, dtype=dtype, copy=False)
    358             else:
--> 359                 data = np.asarray(data, dtype=object)
    360 
    361             # coerce to the object dtype
您可以通过使用 pdb 调试器并逐步查看结果来自己探索这一点。
df1 = pd.DataFrame(data={'col1': [1, 2, 3, 4, 5], 'col2': [10, 11, 12, 13, 14]}, dtype=pd.Int64Dtype())
df2 = pd.DataFrame(data={'col1': [1, 2, 3], 'col2': [10, 11, 12]}, dtype=pd.Int64Dtype())
def test():
    import pdb
    pdb.set_trace()
    df = df2.merge(df1, how='outer', indicator=True, suffixes=('_x', ''))
    return df
df = text()

一些有趣的笔记:
  • 如果您使用 dtype=int而不是 dtype=pd.Int64Dtype()类型实际上符合预期。除了 int 之外,它可能应该与两者相似。类型在 pandas/core/indexes/base.py(359)__new__() 中有不同的逻辑路径除非您有特定用例,否则将 int 解释为“# index-like . That said, you should likely default to using the default int, float, bool` 类型来自 python 而不是 pandas dtypes。
  • df2.merge(df1, how='inner')保留类型,因为不需要重新索引。
  • df1.merge(df2, how='outer')保留类型,因为 df1(基本数据帧)不需要重新索引以合并 df2。
  • 关于python - Pandas 'Int64' 类型合并后转换为 'object' 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58697495/

    相关文章:

    python - Pandas :按行号和列号从数据框中访问数据

    r - 按日期和类别匹配(2 路匹配)

    python - 用 pandas 绘制水平持续时间

    python - 我应该把 key 放在 Flask 的什么地方?

    python - 如何从 pandas 的列中过滤第一次出现的普通话字符并将其放入另一列中

    R:在数据框中插入多行(变量数)

    pandas - 如何解析 df 列中的嵌套列?

    python - 在 django 中的单个 connection.cursor 上执行多个。安全吗?

    python - 你能帮我用python __init__吗

    python - 将函数应用于 pandas dataframe groupby 中的第二列