将对象从解析的 csv 转换为 int Python



这分支了我之前的问题 - 在 Python 中填充 CSV 中的空点。我把这个问题作为一个新问题,因为我觉得我遇到的问题完全改变了我的问题。

我想将对象类型的列中的数据转换为 int,因为值是整数。

填充列中的空插槽后,我仍然遇到错误。我发现我的 csv 文件中的第四列被视为对象而不是 int 而不是所有其他列。这是我的代码:

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

file_name = "myfile.csv"
df = pd.read_csv(file_name)
df.replace(r'^s*$', 0, regex=True)
names = df['name'].values
x = np.arange(len(names))*2
w = 0.40
col2 = df.columns[1]
col3 = df.columns[2]
col4 = df.columns[3]
col5 = df.columns[4]
print(df.dtypes)
df[col4] = df[col4].astype(str).astype(int)
dif = df[col4] - df[col3]
colors = ['Red' if d < -5 else 'Blue' for d in dif]
plt.bar(x-w, df[col2].values, width=w*0.7, label=col2, color = "cyan")
plt.bar(x, df[col3].values, width=w*0.7, label=col3, color = "green")
plt.bar(x+w, df[col4].values, width=w*0.7, label=col4, color = colors)
plt.plot(x, df[col5].values, lw=2, label="Goal", color = "red")
plt.xticks(x, names, rotation='vertical')
plt.ylim([0,100])
plt.show()

我像其他列一样将第 4 个对象列转换为 int 的方法是将 astype 追加为字符串,然后将 int 附加到其末尾,如我的代码所示。我也尝试只附加 astype int,但这也不起作用。这是我当前收到的错误:ValueError: invalid literal for int() with base 10

请参阅我在上面链接的其他帖子,了解我如何到达这里的所有详细信息,以防您觉得它会有所帮助。

编辑 1:根据每个注释请求,以下是代码执行df.replace()之前的 csv 代码段示例。

Col1 Col2 Col3 Col4

Col5
  45 34     23     98 18 66 0 25     
  18          
0          52     56         100

以下是之后的csv:

Col1 Col2 Col3

Col4 Col5
  45 34     23     98 18 66 0 25       0 0 18       
    0
               52     56         100

这是另一种无需替换的方法:

注意:这可能很昂贵,因为此解决方案会重塑数据框。

步骤1:创建数据帧:

s="""
Col1,Col2,Col3,Col4,Col5
45,34,23,98,18
66, ,25, 
18, ,52,56,100
"""
from io import StringIO
df = pd.read_csv(StringIO(s))
print(df)
<小时 />
Col1 Col2  Col3 Col4   Col5
0    45   34    23   98   18.0
1    66         25         NaN
2    18         52   56  100.0

建议的解决方案:

从这里,如果您知道所有列都有数值 ,您可以使用pd.to_numeric函数,将errors参数设置为coerce。 从文档中,我们可以看到强制解析无效的数字条目以NaN

If ‘coerce’, then invalid parsing will be set as NaN


从这里我们可以将数据帧stack()为一个系列,我们在其上应用pd.to_numericerrors='coerce'unstack()回来以获得原始形状,如下所示:

s=df.stack(dropna=False)
final=pd.to_numeric(s,errors='coerce').fillna(0).unstack()
print(final)
<小时 />
Col1  Col2  Col3  Col4   Col5
0  45.0  34.0  23.0  98.0   18.0
1  66.0   0.0  25.0   0.0    0.0
2  18.0   0.0  52.0  56.0  100.0

如果要保存原始NaN即不将它们替换为 0,请不要按照上述建议在df.stack()中传递dropna参数。

s=df.stack()
final=pd.to_numeric(s,errors='coerce').fillna(0).unstack()
print(final)
<小时 />
Col1  Col2  Col3  Col4   Col5
0  45.0  34.0  23.0  98.0   18.0
1  66.0   0.0  25.0   0.0    NaN
2  18.0   0.0  52.0  56.0  100.0

正如克里斯在他的评论中提到的,我已经使用了df=pd.read_clipboard()


... snippet ...
#df = pd.read_csv(file_name)
df=pd.read_clipboard()
df.replace(r'^s*$', 0, regex=True)
print (df)
print (df['Col1'].values)

如果在列 n-name 中更改了"name",则 print 语句将给出以下结果:

>>>    Col1  Col2  Col3  Col4   Col5
>>> 0    45    34    23  98.0   18.0
>>> 1    66     0    25   NaN    NaN
>>> 2    18     0    52  56.0  100.0
>>> [45 66 18]

要替换"NaN",请执行以下操作:

df.fillna(0, inplace=True)在 df 上。 # 一次将其应用于所有列。

因此,如果所有"NaN"都被更改,结果如下所示:

Col1  Col2  Col3  Col4   Col5
0    45    34    23  98.0   18.0
1    66     0    25   0.0    0.0
2    18     0    52  56.0  100.0

对于第 4 列:df['Col4'].fillna(0, inplace=True)

Col1  Col2  Col3  Col4   Col5
0    45    34    23  98.0   18.0
1    66     0    25   0.0    NaN
2    18     0    52  56.0  100.0

print (df['Col4'].values)结果:

>>> [98. 0. 56.]

我还从带有/不带 fillna 选项的剪贴板表中保存了 csv。csv 输出如下所示,使用df.to_csv('blabla1', sep=',', encoding='utf-8')

df.fillna(0, inplace=True)之前:

,Col1,Col2,Col3,Col4,Col5
0,45,34,23,98.0,18.0
1,66,0,25,,
2,18,0,52,56.0,100.0

df.fillna(0, inplace=True)后:

,Col1,Col2,Col3,Col4,Col5
0,45,34,23,98.0,18.0
1,66,0,25,0.0,
2,18,0,52,56.0,100.0

最新更新