我正在尝试根据数量可能不同的列之间的比较在 pandas 中创建一个列,并尝试想出最快、最干净的方法来执行此操作:
id date birth_date_1 birth_date_2
1 1/1/2000 1/3/2000 1/5/2000
1 1/7/2000 1/3/2000 1/5/2000
2 1/2/2000 1/10/2000 1/1/2000
2 1/5/2000 1/10/2000 1/1/2000
3 1/4/2000 NaT NaT
我的目标是创建一个新列来计算当前日期之前的出生日期数量:
id date birth_date_1 birth_date_2 num_born_before_date
1 1/1/2000 1/3/2000 1/5/2000 0
1 1/7/2000 1/3/2000 1/5/2000 2
2 1/2/2000 1/10/2000 1/1/2000 1
2 1/5/2000 1/10/2000 1/1/2000 1
3 1/4/2000 NaT NaT 0
需要注意的是,birth_date 列的数量因运行而异。我不想迭代条目,因为那会非常慢......
编辑:使用np.where
想出了一些肮脏的技巧。不确定是否有更好的方法来做到这一点,特别是在处理 NaT 方面。
NAT2 = pd.to_datetime('01-01-2100') # need this to deal with NaTs
df = df.fillna(NAT2)
df['num_born'] = 0
created_cols = [c for c in df.columns if 'birth_date' in c]
for col in created_cols:
df['num_born'] = np.where((df['date'] >= df[col]),
df['num_born'] + 1, df['num_born'])
df = df.replace(to_replace=NAT2, value=pd.NaT)
最佳答案
因此,假设您的数据框已解析日期时间列(您可以使用 to_datetime
来实现此目的,或者例如在 read_csv
中指定 parse_dates
):
In [64]: df
Out[64]:
id date birth_date_1 birth_date_2
0 1 2000-01-01 2000-01-03 2000-01-05
1 1 2000-01-07 2000-01-03 2000-01-05
2 2 2000-01-02 2000-01-10 2000-01-01
3 2 2000-01-05 2000-01-10 2000-01-01
您现在可以检查“birth_date”列中的值低于“date”列中的值的位置,然后使用 sum
进行计数:
In [65]: df[['birth_date_1', 'birth_date_2']].lt(df['date'], axis=0)
Out[65]:
birth_date_1 birth_date_2
0 False False
1 True True
2 False True
3 False True
In [66]: df[['birth_date_1', 'birth_date_2']].lt(df['date'], axis=0).sum(axis=1)
Out[66]:
0 0
1 2
2 1
3 1
dtype: int64
要处理不同数量的“birth_date”列,您可以使用过滤器
自动执行此操作,如下所示:
In [67]: df.filter(like="birth_date")
Out[67]:
birth_date_1 birth_date_2
0 2000-01-03 2000-01-05
1 2000-01-03 2000-01-05
2 2000-01-10 2000-01-01
3 2000-01-10 2000-01-01
总而言之,这将给出:
In [66]: df.filter(like="birth_date").lt(df['date'], axis=0).sum(axis=1)
Out[66]:
0 0
1 2
2 1
3 1
dtype: int64
关于python - Pandas 与可变列数的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27305324/