我有一个熊猫数据帧,我想以增量方式将行附加到该数据帧。我的问题是,当尝试发生值时,它们的类型会丢失。这对于变得'object'
'boolean'
来说尤其烦人(int
变得float
仍然是一件坏事,但至少程序的其余部分仍然可以运行,只是效率较低):
data1 = pd.DataFrame()
data1['foo'] = 5
print("*n",data1.dtypes)
data2 =pd.DataFrame()
data2['bar'] = True
print("**n",data2.dtypes)
data3 = pd.concat([data1, data2])
print("***n",data3.dtypes)
data4 = data1.append(data2)
print("****n",data4.dtypes)
*
foo int64
dtype: object
**
bar bool
dtype: object
***
bar object
foo float64
dtype: object
****
bar object # <-- bool type becomes object
foo float64
dtype: object
您知道如何预防它吗?
问题的解决方案:
更改列的类型以允许表示由np.nan
表示的缺失值(因为与它追加到的数据帧相比,该行添加或遗漏了一些列)。
根据经验,附加/连接新行以诱导缺失信息将按以下方式更改类型:
int64
-->float64
bool
-->float64
如果使用字典设置新行bool
-->object
如果使用数据帧设置新行
import pandas as pd
# https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.astype.html
# create DataFrame
d = {'col1': [1, 2], 'col2': [3, 4]}
df = pd.DataFrame(data=d)
df.dtypes
col1 int64
col2 int64
dtype: object
# Keep dtypes
ser_types = df.dtypes
ser_types
col1 int64
col2 int64
dtype: object
# Chnange dtypes for test purpose
df = df.astype('float64').copy()
df.dtypes
col1 float64
col2 float64
dtype: object
# Series dtype to dictionary
ser_types.to_dict()
{'col1': dtype('int64'), 'col2': dtype('int64')}
# Chnage dtype from initial df
df = df.astype(ser_types.to_dict()).copy()
df.dtypes
col1 int64
col2 int64
dtype: object
df
col1 col2
0 1 3
1 2 4
您的问题在行和列之间混合。 在熊猫中,每列都有一个类型,每一行获取其每列的类型。
如果执行此操作data1['foo'] = [some values]
则定义一个新列,并且追加两个具有不同列名称的数据帧时,您将:
将 other 行附加到此帧的末尾,返回一个新对象。不在此框架中的列将作为新列添加。
(看这里)
另一方面,使用concat
做数据帧的列堆栈,保持列数据类型。
最后,请注意,您的列分配需要使用括号。
data1['foo'] = [5]
而不是
data1['foo'] = 5
编辑:本着您评论的精神,我做了一个小实验,试图遵循您的意图:
df = pd.DataFrame() # Creating a DF
df['a'] = [1,2,3] # Adding a column of integers
df['b'] = [True, False, True] # Adding a column of Boolean
print df['b'].dtype
>bool
我们看到 col 'b' 确实是布尔值。
添加包含部分数据的行:
df = df.append({'a':1}, ignore_index=True)
print df['b'].dtype
>float64
现在col 'b' 更改为 float64,以支持 NaN 类型。这就是已知的numpy NaN陷阱。
最后,打印df
结果:
print df
a b
0 1.0 1.0
1 2.0 0.0
2 3.0 1.0
3 1.0 NaN