Python 在保持列数据类型的同时将行插入数据框
在维护列数据类型的同时,为未指定的列提供用户定义的填充值,将新行插入现有数据框的最佳方法是什么?下面是一个例子:Python 在保持列数据类型的同时将行插入数据框,python,pandas,dataframe,append,Python,Pandas,Dataframe,Append,在维护列数据类型的同时,为未指定的列提供用户定义的填充值,将新行插入现有数据框的最佳方法是什么?下面是一个例子: 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 = 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
列转换为对象
这里有一个非常老套的解决方案,但感觉不是“正确的方法”:
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
我知道我一定遗漏了什么。这是因为,NaN值是浮点值,而True和False是布尔值。一列中有混合的数据类型,因此Pandas将自动将其转换为object 另一个例子是,如果您有一个包含所有整数值的列,并且附加了一个带有float的值,那么您可以通过将“.0”添加到其余值来将整个列更改为float
编辑 根据注释,这是另一种将对象转换为booldtype的黑客方法
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
正如您所发现的,由于
NaN
是一个float
,将NaN
添加到序列中可能会导致它被上溯到float
或转换为对象。你认为这不是一个理想的结果是正确的
没有直接的方法。我的建议是将输入行数据存储在字典中,并在追加之前将其与默认值字典相结合。请注意,这是因为pd.DataFrame.append
接受dict
参数
在Python3.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
谢谢你的帮助。抱歉,我不太清楚-我确实理解这些列为什么要更改数据类型,但希望找到避免这种情况的最佳方法。似乎在执行追加之前需要处理nan?是的,np.nan
需要处理,通常取决于您正在处理的用例。如果你是一名数据科学家,那么价值观对最终结果有着巨大的影响。我建议将它作为一个对象保留,并为以后的目的维护一个模式。您想评论一下吗?我非常乐意编辑/更新/澄清是否存在严重的缺陷。是的,不知道为什么有人会对此投反对票。你把我乱七八糟的代码简化成了更容易理解的东西…什么!!!!!这就是这个问题的答案!难怪有人否决了这个答案。将列中缺少的值替换为False,使其成为布尔类型。正如问题本身所提到的,这不是正确的方法!如果我错了,请纠正我。此外,熊猫本身通过将np.nan
强制转换为True
将对象列转换为bool。为什么选择False作为默认值?我最初的问题是如何用用户定义的值替换NA值。关键是用户可以选择对他们的用例有意义的内容。在我的例子中,False
对于我试图填充的列是有意义的。