合并更改 Pandas 类型

Mat*_*att 5 python-3.x pandas

我正在使用 Python 3(不知道该信息是否相关)。我有 2 个 Pandas DataFrame(来自read_csv()):CompactSDSS_DR7_to_DR8。合并之前,它们包含以下类型:

Compact.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2070 entries, 0 to 2069
Data columns (total 8 columns):
Group    2070 non-null int64
Id       2070 non-null int64
RA       2070 non-null float64
Dec      2070 non-null float64
z        2070 non-null float64
R        2070 non-null float64
G        2070 non-null float64
objid    2070 non-null int64
dtypes: float64(5), int64(3)
memory usage: 129.5 KB
Run Code Online (Sandbox Code Playgroud)

SDSS_DR7_to_DR8.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 243500 entries, 0 to 243499
Data columns (total 5 columns):
specobjid    243500 non-null int64
dr8objid     243500 non-null int64
dr7objid     243500 non-null int64
ra           243500 non-null float64
dec          243500 non-null float64
dtypes: float64(2), int64(3)
memory usage: 9.3 MB
Run Code Online (Sandbox Code Playgroud)

我执行一个Compact=pd.merge(Compact, SDSS_DR7_to_DR8, left_on=['objid'], right_on=['dr8objid'], how='left'). 执行没有错误,但是结果却乱七八糟。当我检查新 DataFrame 中的类型时,我得到以下信息:

Compact.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 2070 entries, 0 to 2069
Data columns (total 13 columns):
Group        2070 non-null int64
Id           2070 non-null int64
RA           2070 non-null float64
Dec          2070 non-null float64
z            2070 non-null float64
R            2070 non-null float64
G            2070 non-null float64
objid        2070 non-null int64
specobjid    1275 non-null float64
dr8objid     1275 non-null float64
dr7objid     1275 non-null float64
ra           1275 non-null float64
dec          1275 non-null float64
dtypes: float64(10), int64(3)
memory usage: 226.4 KB
Run Code Online (Sandbox Code Playgroud)

因此,在合并期间,dr8objid(以及其他一些)已被强制转换为float64. 这怎么可能,我能做些什么来防止这种情况发生(希望这是合并中混乱的根源)?

编辑所以,更具体地说:如果我创建df

df=pd.DataFrame(data=[[1000000000000000000,1]], columns=['key','data'])
Run Code Online (Sandbox Code Playgroud)

key并且data都是int64。我创建一个转码 df:

trans=pd.DataFrame(data=[[1000000000000000000,2000000000000000000]], 
                   columns=['key','key2'])
Run Code Online (Sandbox Code Playgroud)

其中 2 个键是int64. 然后

df2 = pd.merge(df, trans, on=['key'], how='left')
Run Code Online (Sandbox Code Playgroud)

给出了一个很好的结果, 和keykey2data仍然是int64

尽管如此,如果我定义

df=pd.DataFrame(data=[[1000000000000000000,1],[1000000000000000001,2]],
                columns=['key','data'])
Run Code Online (Sandbox Code Playgroud)

现在合并后,我得到

现在已经key2切换到float64. 如何防止这种情况发生?是因为NaN必须连接浮子吗?如果是这样,是否可以设置合并来定义合并结果为0或-1(如果没有对应关系),保持整个列为int64

w-m*_*w-m 4

更新:在 Pandas 0.24 中,现在有可空整数数据类型

截至撰写本文时,Pandas 似乎并未为合并结果选择可为空的 int 数据类型。但可以Int64在合并之前将两个数组都转换为可空 int 类型。

考虑

df=pd.DataFrame(data=[[1000000000000000000,1],[1000000000000000001,2]],
                columns=['key','data']).astype("Int64")
trans=pd.DataFrame(data=[[1000000000000000000,2000000000000000000]], 
                   columns=['key','key2']).astype("Int64")
df2 = pd.merge(df, trans, on=['key'], how='left')
Run Code Online (Sandbox Code Playgroud)

结果:

>>> df2
                   key  data                 key2
0  1000000000000000000     1  2000000000000000000
1  1000000000000000001     2                 <NA>

>>> df2.dtypes
key     Int64
data    Int64
key2    Int64
dtype: object
Run Code Online (Sandbox Code Playgroud)

原始答案,对于 Pandas < v0.24:

是因为 NaN 必须与浮点数连接吗?

正确的。int 中没有 NaN 值,因此缺失值只能用浮点数表示。

您可以在合并之前过滤数据,确保没有创建 NaN。

或者您可以在合并后用您选择的值填充 NaN,然后​​恢复数据类型。

  • @CesareIurlaro NaN 通常只为浮点值定义,根本不适用于固定大小的整数,请参见 https://en.wikipedia.org/wiki/NaN。或者只是在Python中尝试“int(float('nan'))”,它会抛出“ValueError:无法将float NaN转换为整数”。所以这不是 Pandas 的设计决定,而是 Python(以及任何常见编程语言)的工作原理。有趣的是,Pandas 添加了一个新的实验数据类型来解决这个问题,请参阅我对答案的编辑! (2认同)