python - Pandas 与可变列数的比较

标签 python pandas

我正在尝试根据数量可能不同的列之间的比较在 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/

相关文章:

python - 将 pandas 数据框转换为带索引的元组列表

python 从函数名看完整定义

python - 用 python pandas 解析日志文件

python - 循环遍历数据框中的数组并按组绘制

python - 在打开的文件上使用 Pandas read_csv() 两次

python - Pandas 移动行 block

python - 从数据框列中获取数据作为元组列表

java - 在 JSON 中包含文本文件

python - 在python中转换pandas dataframe datetime格式

python - 如何利用 ffmpeg 从视频流中提取关键帧并仅打印这些帧中存在的标签?