Pandas DataFrame iloc 破坏了数据类型

gha*_*ten 8 python python-3.x pandas

有熊猫 0.19.2。

下面是一个例子:

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

输出:

A      int64
B    float64
dtype: object
Run Code Online (Sandbox Code Playgroud)

现在一切看起来都很好,但我不喜欢的是(注意,第一个调用是 a pd.Series.iloc,第二个是pd.DataFrame.iloc

print(type(testdf.A.iloc[0]))
print(type(testdf.iloc[0].A))
Run Code Online (Sandbox Code Playgroud)

输出:

<class 'numpy.int64'>
<class 'numpy.float64'>
Run Code Online (Sandbox Code Playgroud)

我在试图理解为什么pd.DataFrame.join()操作返回几乎没有两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
Run Code Online (Sandbox Code Playgroud)

什么被认为是完全相同的 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
Run Code Online (Sandbox Code Playgroud)

UPD2复制@EdChum 评论joinmerge行为。问题是A.join(B, on='C')将使用 index inA并将其与 column 连接B['C'],因为默认情况下连接使用索引。就我而言,我只是使用合并来获得理想的结果。

piR*_*red 7

这正如预期的那样。 pandas每列的轨道dtypes。当你打电话时,testdf.iloc[0]你是在向熊猫询问行。它必须将整行转换为一个系列。该行包含一个浮动。因此,作为一个系列的行必须是浮动的。

但是,似乎当 pandas 使用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'>
Run Code Online (Sandbox Code Playgroud)

改为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'>
Run Code Online (Sandbox Code Playgroud)

因此,似乎当pandas使用lociloc它进行一些跨行转换时,我仍然不完全理解。loc我确信这与和的性质不同于iloc, at,iat的事实有关,get_value因为ilocloc允许您使用索引数组和布尔数组访问数据帧。而atiat、 和get_value一次仅访问一个单元格。


尽管那样

testdf.loc[0, 'A'] = 10

print(type(testdf.at[0, 'A']))
Run Code Online (Sandbox Code Playgroud)

当我们通过 分配到该位置时locpandas确保dtype保持一致。