2017-01-15 86 views
4

拥有熊猫0.19.2。熊猫DataFrame iloc破坏数据类型

下面是一个例子:

testdf = pd.DataFrame({'A': [1, 2, 3, 4], 'B': [1.0, 2.0, 3.0, 4.0]}) 
testdf.dtypes 

输出:

A  int64 
B float64 
dtype: object 

一切都看起来不错的了,但我不喜欢的是,(注,即第一个电话是pd.Series.iloc和第二个是pd.DataFrame.iloc

print(type(testdf.A.iloc[0])) 
print(type(testdf.iloc[0].A)) 

输出:

<class 'numpy.int64'> 
<class 'numpy.float64'> 

我发现它在试图理解为什么pd.DataFrame.join()操作返回几乎没有交集2个int64列,而应该有不少。 我的猜测是因为可能与此行为有关的类型不一致,但我不确定...我的短期调查揭示了上述事情,现在我感到困惑了一些。

如果有人知道如何解决它 - 我会非常感激任何提示!

UPD

感谢@EdChum征求意见。因此,这里的例子我生成的数据,并加入/合并行为

testdf.join(testdf, on='A', rsuffix='3')

A B A3 B3 
0 1 1.0 2.0 2.0 
1 2 2.0 3.0 3.0 
2 3 3.0 4.0 4.0 
3 4 4.0 NaN NaN 

什么被认为是不太一样 pd.merge(left=testdf, right=testdf, on='A') 回报

A B_x B_y 
0 1 1.0 1.0 
1 2 2.0 2.0 
2 3 3.0 3.0 
3 4 4.0 4.0 

UPD2复制@EdChum评论joinmerge的行为。问题在于A.join(B, on='C')将使用A中的索引并将其与B['C']列联接,因为默认情况下联接使用索引。在我的情况下,我只是使用合并来获得期望的结果。

+1

'iloc'返回你的一系列行,没有满足int和float的dtype因此显示'object',因为你的行是混合dtype,这里有什么问题? – EdChum

+0

如果你试图匹配的列是int64,那么值比较应该按预期工作,如果它们是float,那么这可能会遇到精度问题,这与上面显示的内容无关 – EdChum

+0

@EdChum好吧,谢谢,你的观点解释了我的例子。我的列不是浮动的,所以这是一个问题。例如,我可以在两个表中手动查找指定的值,但是,连接失败。 –

回答

2

这是预期的。 pandas每列跟踪dtypes。当你打电话给testdf.iloc[0]时,你会问大熊猫一排。它必须将整行转换为一系列。该行包含一个浮点数。因此,作为一个系列的行必须是浮动的。

但是,看来,当熊猫使用lociloc当你使用一个单一的__getitem__

这里有一些有趣的测试案例的testdf有一个int

testdf = pd.DataFrame({'A': [1, 2, 3, 4]}) 

print(type(testdf.iloc[0].A)) 
print(type(testdf.A.iloc[0])) 

<class 'numpy.int64'> 
<class 'numpy.int64'> 

更改它使这种转换它对OP测试案例

testdf = pd.DataFrame({'A': [1, 2, 3, 4], 'B': [1.0, 2.0, 3.0, 4.0]}) 

print(type(testdf.iloc[0].A)) 
print(type(testdf.A.iloc[0])) 

<class 'numpy.float64'> 
<class 'numpy.int64'> 

print(type(testdf.loc[0, 'A'])) 
print(type(testdf.iloc[0, 0])) 
print(type(testdf.at[0, 'A'])) 
print(type(testdf.iat[0, 0])) 
print(type(testdf.get_value(0, 'A'))) 

<class 'numpy.float64'> 
<class 'numpy.float64'> 
<class 'numpy.int64'> 
<class 'numpy.int64'> 
<class 'numpy.int64'> 

因此,它似乎pandas使用lociloc时,它会对行进行一些转换,但我仍不完全明白。我相信这与lociloc的性质不同于at,iat,get_value这一事实有关,因为ilocloc允许您使用索引数组和布尔数组访问数据帧。而atiatget_value一次只能访问单个单元。


尽管

​​

当我们通过loc分配到该位置,pandas确保dtype保持一致。

+0

感谢您提供非常详细的解释! –