当我合并两个数据帧时,如何防止 Pandas 将我的整数转换为浮点数?
Posted
技术标签:
【中文标题】当我合并两个数据帧时,如何防止 Pandas 将我的整数转换为浮点数?【英文标题】:How to prevent Pandas from converting my integers to floats when I merge two dataFrames? 【发布时间】:2016-11-21 12:27:36 【问题描述】:这是我的代码:
import pandas as pd
left = pd.DataFrame('AID': [1, 2, 3, 4],
'D': [2011, 2011,0, 2011],
'R1': [0, 1, 0, 0],
'R2': [1, 0, 0, 0] )
right = pd.DataFrame('AID': [1, 2, 3, 4],
'D': [2012, 0,0, 2012],
'R1': [0, 1, 0, 0],
'R2': [1, 0, 0, 0] )
result = left.merge(right, how = 'outer')
当我打印我的结果数据帧时,整数值现在是浮点数:
AID D R1 R2
0 1.0 2011.0 0.0 1.0
1 2.0 2011.0 1.0 0.0
2 3.0 0.0 0.0 0.0
3 4.0 2011.0 0.0 0.0
4 1.0 2012.0 0.0 1.0
5 2.0 0.0 1.0 0.0
6 4.0 2012.0 0.0 0.0
如何防止这种情况发生?
【问题讨论】:
***.com/questions/21291259/…的可能重复 显然这是一个错误,将在 0.18.2 中修复 github.com/pydata/pandas/issues/8596 我可以重现此问题并已投票重新打开。重现所需的代码略有不同 left = pd.DataFrame('AID': [1, 2, 3, 4], 'D': [2011, 2011,0, 2011], 'R1': [0, 1, 0, 0], ) 右 = pd.DataFrame('AID': [1, 2, 3, 4], 'D': [2012, 0,0, 2012], 'R2': [1 , 0, 0, 0] ) 结果 = left.merge(right, how = 'outer', on=['AID', 'D']) 结果 请注意,如果由于两个数据帧的索引或列之间的不匹配而产生 NaN 值,则浮点数可能会出现在人们只期望整数的地方。请注意如何指定合并类型,即如何在.merge()
中设置how
kwarg。这是我问题的根源。最后,我尝试了 Rakesh 的代码,但无法重现他/她的错误。
【参考方案1】:
此错误已在 pandas v0.19.0. 中修复:
合并现在将保留连接键的数据类型
但请注意,您可以使用以下方法将数据框中的所有列转换为 int
dtype:
result = result.astype(int)
如果连接中有不匹配的记录,则此行为does still occur,因此结果中的NaN
s。在这种情况下,您需要将dtype更改为extension type'Int64'
来处理NaN
s:
result = result.astype('Int64')
【讨论】:
【参考方案2】:您可以将浮点数转换回 using
result = left.merge(right, on='AID', how = 'outer')
result['D_x']=result['D_x'].astype('Int64')
result['R1_x']=result['R1_x'].astype('Int64')
result['R2_x']=result['R2_x'].astype('Int64')
result['D_y']=result['D_y'].astype('Int64')
result['R1_y']=result['R1_y'].astype('Int64')
result['R2_y']=result['R2_y'].astype('Int64')
如果数据有空或缺失数据
import numbers
import math
left = pd.DataFrame('AID': [1, 2, 3, 4],
'D': [2011, 2011,0, 2011],
'R1': [0, 1, 0, 0],
'R2': [1, 0, 0, 0] )
right = pd.DataFrame('AID': [1, 2, 3, 4],
'D': [2012, 0,0, 2012],
'R1': [0, 1, 0, 0],
'R2': [1, 0, 0, 0] )
result = left.merge(right, how = 'outer')
result['AID']=[int(val) if isinstance(val,numbers.Number) & (math.isnan(val)==False) else 0 for val in result['AID']]
result['D']=[int(val) if isinstance(val,numbers.Number) & (math.isnan(val)==False) else 0 for val in result['D']]
result['R1']=[int(val) if isinstance(val,numbers.Number) & (math.isnan(val)==False) else 0 for val in result['R1']]
result['R2']=[int(val) if isinstance(val,numbers.Number) & (math.isnan(val)==False) else 0 for val in result['R2']]
print(result)
print(result.isna())
输出
AID D R1 R2
0 1 2011 0 1
1 2 2011 1 0
2 3 0 0 0
3 4 2011 0 0
4 1 2012 0 1
5 2 0 1 0
6 4 2012 0 0
AID D R1 R2
0 False False False False
1 False False False False
2 False False False False
3 False False False False
4 False False False False
5 False False False False
6 False False False False
然后,您可以将 nan 值替换为:均值、0 或插值
固定 D 列
def interpolate_list(y):
idx = np.nonzero(y)
x = np.arange(len(y))
interp = interp1d(x[idx],y[idx])
new_values = interp(x)
return new_values
interp_d=interpolate_list(np.array(result['D']))
data=list(zip(interp_d,result['D']))
result['D']=[item[0] if item[1]==0 else item[1] for item in data]
print(result)
输出
AID D R1 R2
0 1 2011.0 0 1
1 2 2011.0 1 0
2 3 2011.0 0 0
3 4 2011.0 0 0
4 1 2012.0 0 1
5 2 2012.0 1 0
6 4 2012.0 0 0
【讨论】:
这行得通,除非有不匹配的记录(如另一个响应中提到的),其中某些字段包含NaN
。在这种情况下,您需要.astype('Int64')
。【参考方案3】:
我遇到了同样的问题,这是因为合并后我在重铸列中得到了一些 NaN 值。
所以,我的“之前”列是 int32,而“现在”表是 float64。
当我想将它重铸为 int32 时,我遇到了这个问题:
“ValueError:无法将非有限值(NA 或 inf)转换为整数”
所以我把它留在 float64 上:D
【讨论】:
以上是关于当我合并两个数据帧时,如何防止 Pandas 将我的整数转换为浮点数?的主要内容,如果未能解决你的问题,请参考以下文章
TypeError: unhashable type: 'numpy.ndarray' 合并来自 BigQuery 的 pandas 数据帧时
当我们尝试将巨大的 Pandas 数据帧(40-50 百万行)转换为 Spark 2.0 数据帧时如何提高性能