Pandas.read_excel有时错误地将布尔值读取为1/0

时间:2018-08-02 20:51:16

标签: python excel pandas

我需要将一个非常大的Excel文件读入DataFrame。该文件包含字符串,整数,浮点数和布尔数据,以及丢失的数据和完全空的行。值得注意的是,某些单元格值是从单元格公式和/或VBA导出的-尽管从理论上讲应该不会影响任何内容。

正如标题所述,pandas有时将布尔值读取为float或int 1和0,而不是True和False。它似乎与空行的数量和其他数据的类型有关。为了简单起见,我只链接一个复制问题的2页Excel文件。 Boolean_1.xlsx

代码如下:

import pandas as pd
df1 = pd.read_excel('Boolean_1.xlsx','Sheet1')
df2 = pd.read_excel('Boolean_1.xlsx','Sheet2')
print(df1, '\n' *2, df2)

这是印刷品。主要注意行ZBA,这两个表中的值均相同,但数据帧中的值不同:

  Name stuff  Unnamed: 1 Unnamed: 2 Unnamed: 3
0         AFD          a        dsf        ads
1         DFA          1          2          3
2         DFD      123.3       41.1       13.7
3        IIOP        why        why        why
4         NaN        NaN        NaN        NaN
5         ZBA      False      False       True 

   Name adslfa  Unnamed: 1  Unnamed: 2  Unnamed: 3
0        asdf         6.0         3.0         6.0
1         NaN         NaN         NaN         NaN
2         NaN         NaN         NaN         NaN
3         NaN         NaN         NaN         NaN
4         NaN         NaN         NaN         NaN
5         ZBA         0.0         0.0         1.0

我还可以在实际上正在处理的大文件中(是​​)获得整数1和0的输出,但是无法轻松复制它。

是什么原因导致这种不一致,有没有办法强迫熊猫读取应该读取的布尔值?

2 个答案:

答案 0 :(得分:2)

按类型/列应用熊猫类型转换。通常,Pandas不适用于混合类型或object dtype。您应该期望内部逻辑确定系列的最有效dtype。在这种情况下,Pandas选择了float dtype作为适用于包含floatbool值的序列的类型。我认为这是有效而整洁的。

但是,正如您所指出的,当您具有转置的输入数据集时,这将不起作用。让我们从头开始建立一个示例:

import pandas as pd, numpy as np

df = pd.DataFrame({'A': [True, False, True, True],
                   'B': [np.nan, np.nan, np.nan, False],
                   'C': [True, 'hello', np.nan, True]})

df = df.astype({'A': bool, 'B': float, 'C': object})

print(df)

       A    B      C
0   True  NaN   True
1  False  NaN  hello
2   True  NaN    NaN
3   True  0.0   True

选项1:更改“行dtype”

您可以在不转置数据的情况下,更改连续对象的dtype。这将迫使系列B具有object dtype,即存储指向任意类型的指针的系列:

df.iloc[3] = df.iloc[3].astype(bool)

print(df)

       A      B      C
0   True    NaN   True
1  False    NaN  hello
2   True    NaN    NaN
3   True  False   True

print(df.dtypes)

A      bool
B    object
C    object
dtype: object

选项2:转置并转换为布尔值

我认为,这是更好的选择,因为数据类型已附加到特定类别/一系列输入数据中。

df = df.T                   # transpose dataframe
df[3] = df[3].astype(bool)  # convert series to Boolean

print(df)

      0      1     2      3
A  True  False  True   True
B   NaN    NaN   NaN  False
C  True  hello   NaN   True

print(df.dtypes)

0    object
1    object
2    object
3      bool
dtype: object

答案 1 :(得分:0)

Read_excel将基于具有值的列的第一行来确定每列的dtype。如果该列的第一行为空,则Read_excel将继续到下一行,直到找到一个值。

在Sheet1中,具有B,C和D列中的值的第一行包含字符串。因此,所有后续行将被视为这些列的字符串。在这种情况下,FALSE = False

在Sheet2中,具有B,C和D列中的值的第一行包含整数。因此,所有后续行将被视为这些列的整数。在这种情况下,FALSE = 0。