考虑以下操作序列:
- 创建具有以下类型
int64
、float64
的两列的数据帧 - 通过将所有列转换为
object
创建新框架 - 检查新数据帧
- 持久化新数据帧
- 期望第二列持久化,如第三步所示:即作为字符串,而不是作为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"> 您可以使用: 而不是在步骤2中铸造。df.to_csv("df.csv",float_format='%g', index=False, sep="t")
我对熊猫不太好,还在学习。我看了一些解决方案,想为什么不在我们将数据发送到csv文件之前对其进行应用。
以下是我将值打印为1
和5
而不是1.0
和5.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(将失败。