在维护列数据类型的同时,将新行插入现有pandas DataFrame的最佳方法是什么,同时为未指定的列提供用户定义的填充值?这是一个例子:
df = pd.DataFrame({
'name': ['Bob', 'Sue', 'Tom'],
'age': [45, 40, 10],
'weight': [143.2, 130.2, 34.9],
'has_children': [True, True, False]
})
假设我要添加仅传递name
和age
的新记录。为了维护数据类型,我可以从df
复制行,修改值,然后将df
附加到副本,例如
columns = ('name', 'age')
copy_df = df.loc[0:0, columns].copy()
copy_df.loc[0, columns] = 'Cindy', 42
new_df = copy_df.append(df, sort=False).reset_index(drop=True)
但是将bool
列转换为对象。
这是一个真正的hacky解决方案,感觉不像是正确的方式"这样做:
columns = ('name', 'age')
copy_df = df.loc[0:0].copy()
missing_remap = {
'int64': 0,
'float64': 0.0,
'bool': False,
'object': ''
}
for c in set(copy_df.columns).difference(columns)):
copy_df.loc[:, c] = missing_remap[str(copy_df[c].dtype)]
new_df = copy_df.append(df, sort=False).reset_index(drop=True)
new_df.loc[0, columns] = 'Cindy', 42
我知道我一定错过了什么。
答案 0 :(得分:0)
这是因为,NaN值是一个浮点数,但是True和False是bool。一列中有混合dtypes,因此Pandas会自动将其转换为对象。
另一个例子是,如果你有一个包含所有整数值的列并且使用float附加一个值,那么pandas会通过在剩余值中添加“.0”来将整个列更改为float。
修改强>
基于评论,另一种将对象转换为bool dtype的hacky方法。
df = pandas.DataFrame({
'name': ['Bob', 'Sue', 'Tom'],
'age': [45, 40, 10],
'weight': [143.2, 130.2, 34.9],
'has_children': [True, True, False]
})
row = {'name': 'Cindy', 'age': 12}
df = df.append(row, ignore_index=True)
df['has_children'] = df['has_children'].fillna(False).astype('bool')
现在,新数据框如下所示:
age has_children name weight
0 45 True Bob 143.2
1 40 True Sue 130.2
2 10 False Tom 34.9
3 12 False Cindy NaN
答案 1 :(得分:0)
正如您所发现的那样,由于NaN
是float
,因此向系列中添加NaN
可能会导致它被上传到float
或转换为object
}。你是对的,确定这不是一个理想的结果。
没有直截了当的方法。我的建议是将输入行数据存储在字典中,并在附加之前将其与默认字典组合。请注意,这是有效的,因为pd.DataFrame.append
接受dict
参数。
在Python 3.6中,您可以使用语法{**d1, **d2}
将两个词典与第二个词典组合起来。
default = {'name': '', 'age': 0, 'weight': 0.0, 'has_children': False}
row = {'name': 'Cindy', 'age': 42}
df = df.append({**default, **row}, ignore_index=True)
print(df)
age has_children name weight
0 45 True Bob 143.2
1 40 True Sue 130.2
2 10 False Tom 34.9
3 42 False Cindy 0.0
print(df.dtypes)
age int64
has_children bool
name object
weight float64
dtype: object