这分支了我之前的问题 - 在 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 代码段示例。
Col5
45 34 23 98 18 66 0 25
18
0 52 56 100
以下是之后的csv:
Col1 Col2 Col3Col4 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_numeric
errors='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