将行插入Pandas DataFrame,同时维护列数据类型[英] Insert rows into pandas DataFrame while maintaining column data types

本文是小编为大家收集整理的关于将行插入Pandas DataFrame,同时维护列数据类型的处理方法,想解了将行插入Pandas DataFrame,同时维护列数据类型的问题怎么解决?将行插入Pandas DataFrame,同时维护列数据类型问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

在维护列数据类型的同时以及同时为未指定的列的用户定义的填充值时,将新行插入现有的pandas数据框中的最佳方法是什么?这是一个例子:

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是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

其他推荐答案

这是因为,NAN值是浮点,但真和否是布尔.一列中有混合的dtypes,因此熊猫会自动将其转换为对象.

另一个实例是,如果您的列具有所有整数值并用float附加值,则PANDAS将整列更改为float通过将.0'添加到其余值中.


编辑

根据评论,另一种将对象转换为bool dtype的方法.

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

本文地址:https://www.itbaoku.cn/post/1728098.html