熊猫的"to_csv"与打印的行为方式不同



考虑以下操作序列:

  1. 创建具有以下类型int64float64的两列的数据帧
  2. 通过将所有列转换为object创建新框架
  3. 检查新数据帧
  4. 持久化新数据帧
  5. 期望第二列持久化,如第三步所示:即作为字符串,而不是作为float64

图示如下:

# Step 1
df = pd.DataFrame.from_dict({'a': [3, 2, 1, 0], 'b': [1, 500.43, 256.13, 5]})  
# Step 2
df2 = df.astype(object)
# Step 3
df2.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 2 columns):
#   Column  Non-Null Count  Dtype 
---  ------  --------------  ----- 
0   a       4 non-null      object
1   b       4 non-null      object
dtypes: object(2)
memory usage: 192.0+ bytes
# NOTE notice how column `b` is rendered
df2
a       b
0  3       1
1  2  500.43
2  1  256.13
3  0       5
# Step 4
df2.to_csv("/tmp/df2", index=False,  sep="t")

现在让我们检查生成的输出:

$ cat df2
a   b
3   1.0
2   500.43
1   256.13
0   5.0

请注意列b是如何持久化的:即使数据类型是object,小数位数仍然存在于舍入数字中。为什么会发生这种情况?我在这里错过了什么?

我使用的是Pandas 1.1.2和Python 3.7.9。

我认为,'object'是NumPy/pands数据类型,而不是python数据类型之一。如果运行:

type(df2.iloc[0,1])

在步骤4之前,您将获得"float">数据类型,即使它已经更改为的"object">

您可以使用:

df.to_csv("df.csv",float_format='%g', index=False, sep="t")

而不是在步骤2中铸造。

我对熊猫不太好,还在学习。我看了一些解决方案,想为什么不在我们将数据发送到csv文件之前对其进行应用。

以下是我将值打印为15而不是1.05.0所做的操作

df中的值是string、float、int的混合

import pandas as pd
df = pd.DataFrame.from_dict({'a': [3, 2, 1, 's', 't'], 'b': [1, 500.43, 256.13, 5, 'txt']})  
df2 = df.astype(object)
def convert(x):
a = []
for i in x.to_list():
a.append(coerce(i))
return pd.Series(a)

#return pd.Series([str(int(i)) if int(i) == i else i for i in x.to_list()])
def coerce(y):
try:
p = float(y)
q = int(y)
if p != q:
return str(p)
else:
return str(q)
except:
return str(y)
df2.apply(convert).to_csv("abc.txt", index=False, sep="t")

文件中的输出将是:

a   b
3   1
2   500.43
1   256.13
s   5
t   txt

df中的所有值都是数字(整数或浮点(

import pandas as pd
df = pd.DataFrame.from_dict({'a': [3, 2, 1, 0], 'b': [1, 500.43, 256.13, 5]})  
df2 = df.astype(object)
def convert(x):
return pd.Series([str(int(i)) if int(i) == i else i for i in x.to_list()])
df2.apply(convert).to_csv("abc.txt", index=False, sep="t")

输出如下:

a   b
3   1
2   500.43
1   256.13
0   5

这里我假设df2中的所有值都是数字。如果它有一个字符串值,那么int(i(将失败。

最新更新