pandas:在 DataFrame 中组合两列

Posted

技术标签:

【中文标题】pandas:在 DataFrame 中组合两列【英文标题】:pandas: combine two columns in a DataFrame 【发布时间】:2012-06-13 21:41:39 【问题描述】:

我有一个熊猫DataFrame,其中有多个列:

Index: 239897 entries, 2012-05-11 15:20:00 to 2012-06-02 23:44:51
Data columns:
foo                   11516  non-null values
bar                   228381  non-null values
Time_UTC              239897  non-null values
dtstamp               239897  non-null values
dtypes: float64(4), object(1)

其中foobar 是包含相同数据但名称不同的列。有没有办法将组成foo 的行移动到bar,理想情况下同时保持bar 的名称?

最后 DataFrame 应该显示为:

Index: 239897 entries, 2012-05-11 15:20:00 to 2012-06-02 23:44:51
Data columns:
bar                   239897  non-null values
Time_UTC              239897  non-null values
dtstamp               239897  non-null values
dtypes: float64(4), object(1)

即组成 bar 的 NaN 值被 foo 中的值替换。

【问题讨论】:

【参考方案1】:

您可以直接使用fillna并将结果分配给列'bar'

df['bar'].fillna(df['foo'], inplace=True)
del df['foo']

一般例子:

import pandas as pd
#creating the table with two missing values
df1 = pd.DataFrame('a':[1,2],'b':[3,4], index = [1,2])
df2 = pd.DataFrame('b':[5,6], index = [3,4])
dftot = pd.concat((df1, df2))
print dftot
#creating the dataframe to fill the missing values
filldf = pd.DataFrame('a':[7,7,7,7])

#filling 
print dftot.fillna(filldf)

【讨论】:

但请注意,由于 filldf 的索引为 0..3 而 dftot 的索引为 1..4,因此 dftot.fillna(filldf)['a'][4] 将为 nan。不是 7.0【参考方案2】:

试试这个:

pandas.concat([df['foo'].dropna(), df['bar'].dropna()]).reindex_like(df)

如果您希望该数据成为新列bar,只需将结果分配给df['bar']

【讨论】:

我没有看到 concat 作为 pandas 命名空间中的函数;我不确定我错过了什么。 你有什么版本的熊猫?该函数记录在这里:pandas.pydata.org/pandas-docs/stable/… 我正在运行不包含 concat 功能的 pandas 版本 0.6.1。升级到 v 0.7.3 将 concat 带入命名空间。奇迹般有效!谢谢。【参考方案3】:

更现代的 pandas 版本(至少从 0.12 开始)具有用于 DataFrame 和 Series 对象的 combine_first() and update() 方法。例如,如果你的 DataFrame 被称为 df,你会这样做:

df.bar.combine_first(df.foo)

这只会改变 bar 列的 Nan 值以匹配 foo 列,并且会在原地这样做。要用foo 中的值覆盖bar 中的非Nan 值,您可以使用update() 方法。

【讨论】:

【参考方案4】:

另一个选项,在框架上使用.apply() 方法。您可以根据现有数据重新分配列...

import pandas as pd
import numpy as np

# get your data into a dataframe

# replace content in "bar" with "foo" if "bar" is null
df["bar"] = df.apply(lambda row: row["foo"] if row["bar"] == np.NaN else row["bar"], axis=1) 

# note: change 'np.NaN' with null values you have like an empty string

【讨论】:

感谢@Veenit 的收获【参考方案5】:

您也可以使用numpy 来做到这一点。

df['bar'] = np.where(pd.isnull(df['bar']),df['foo'],df['bar'])

【讨论】:

以上是关于pandas:在 DataFrame 中组合两列的主要内容,如果未能解决你的问题,请参考以下文章

按两列分组并计算 Pandas 中每个组合的出现次数

在 pandas DataFrame 中有效地搜索列表值的组合

如何在 Pandas 中组合文本行

Pandas实战教程 | 两列相减

Pandas实战教程 | 两列相减

pandas使用dataframe中的两列时间对象数据列作差生成时间差数据列筛选dataframe数据中时间差(timedelta对象)大于指定阈值的数据行