在 python 中用 None 替换字符串时,来自 GCP 存储的 csv 文件的值更改了值

问题描述

我正在读取存储在 GCP 存储上的 csv 文件,我想用 None 替换字符串“na”。最终表中有一些非常混乱的数据点,因此我制作了一些示例来说明问题。

首先,我读取 csv 文件代码

import pandas as pd
# Storage url is the url of the GCS that stores my files and 
# blob is the name of the desired file
data = pd.read_csv(storage_url+blob).replace('na',None)
print(data)

一个 csv 样本:

col1,col2,col3,col4,col5
1,2,na,2
na,3,na
na,5
5,56,4,5,6,7,na

结果:

  col1 col2 col3 col4 col5
0    1    2   na   na    2
1    1    2    2    3    2
2    1    2    2  NaN    5
3    5   56    4    5    2
4    5    4    6    7    2

因此您可以在这里看到,有些值被替换为 NaN,有些则没有。

对于第二个示例,不仅部分值没有被替换为 NaN,它们原来的 'na' 字符串被替换为之前一行的数值。

construction_number,price_from_euro,price_to_euro,project_id,site_id
6,12023,17844
7,17844
8,17844
9,17844
10,17844
11,17844
13,458000,17844
14,17844
17,17844
18,17844
19,17844
21,17844
22,17844

结果:

    construction_number price_from_euro price_to_euro  project_id  site_id
0                     6              na            na       12023    17844
1                     7              na            na       12023    17844
2                     8              na            na       12023    17844
3                     9              na            na       12023    17844
4                    10              na            na       12023    17844
5                    11              na            na       12023    17844
6                    13          458000        458000       12023    17844
7                    14          458000        458000       12023    17844
8                    17          458000        458000       12023    17844
9                    18          458000        458000       12023    17844
10                   19          458000        458000       12023    17844
11                   21          458000        458000       12023    17844
12                   22          458000        458000       12023    17844

所以您可以看到只有 1 行带有 price_from_euro=458000,在读取的 Pandas 数据框中现在有 7 行。这是怎么回事?我不需要解决方案,我只想了解为什么会这样。我没有在网上找到任何答案。

解决方法

使用na_values='na'

import pandas as pd
from io import StringIO # for reproducibility

csv1 = """col1,col2,col3,col4,col5
1,2,na,2
na,3,na
na,5
5,56,4,5,6,7,na"""

df = pd.read_csv(StringIO(csv1),na_values='na')
print(df)

输出:

   col1  col2  col3  col4  col5
0   1.0   2.0   NaN   NaN   2.0
1   NaN   NaN   2.0   3.0   NaN
2   NaN   2.0   2.0   NaN   5.0
3   5.0  56.0   4.0   5.0   2.0
4   NaN   4.0   6.0   7.0   NaN

当 Pandas 尝试解析您的文件时,它会尝试确定列的类型,您的列有数字和字符串,所以我认为它变得混乱了。 Pandas 在输入列时效果最佳。

如果我们运行:

df = pd.read_csv(StringIO(csv1),na_values='na')
print(df.dtypes)

我们得到:

col1    float64
col2    float64
col3    float64
col4    float64
col5    float64

没有na_values='na'

col1    object
col2    object
col3    object
col4    object
col5    object