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
对于我试图填充的列是有意义的。