如何在Pandasgroupby对象中使用IF NOT IN?

5jvtdoz2  于 2023-03-11  发布在  其他
关注(0)|答案(1)|浏览(73)

我有这样一个数据。

import pandas as pd
import numpy as np
# create a sample DataFrame
data = {'ID': [1, 1, 1, 2, 2, 2],
        'timestamp': ['2022-01-01 12:00:00', '2022-01-01 13:00:00', '2022-01-01 18:00:00',
                      '2022-01-01 12:02:00', '2022-01-01 13:02:00', '2022-01-01 18:02:00'],
        'value1': [10, 20, 30, 40, 50, 60],
        'gender': ['M', 'M', 'F', 'F', 'F', 'M'],
        'age': [20, 25, 30, 35, 40, 45]}
df = pd.DataFrame(data)

# extract the date from the timestamp column
df['date'] = pd.to_datetime(df['timestamp']).dt.date

我想在这个 Dataframe 中获取时间戳值并枚举它们。然后,我将获取时间戳的单个值,并检查groupby对象是否存在。如果不存在,我将追加它。下面是我的方法。

for indx, single_date in enumerate(df.timestamp):
    #print(single_date)
    if df.timestamp[indx] not in df.groupby(['ID'],as_index=False):
        df2 = pd.DataFrame([[df.ID[indx],df.timestamp[indx],np.nan,df.gender[indx],df.age[indx]]],
                           columns=['ID', 'timestamp', 'value1', 'gender', 'age'])
        #print(df2)
        df2['timestamp'] = pd.to_datetime(df2['timestamp'])
        new_ckd = df.groupby(['ID']).apply(lambda y: pd.concat([y, df2]))
new_ckd['timestamp'] = pd.to_datetime(new_ckd['timestamp'])
new_ckd = new_ckd.sort_values(by=['timestamp'], ascending=True).reset_index(drop=True)
#print(new_ckd)
    #print(df.ID[indx])
print(df.groupby(['ID'],as_index=False).timestamp.apply(print))
for indx, single_date in enumerate(df.timestamp):
    #print(df.timestamp[indx])
    if df.timestamp[indx] in df.groupby(['ID'],as_index=False).timestamp:
        print('a')

我意识到groupby对象上的IF NOT IN条件不起作用。我怎样才能使它起作用呢?
我拥有的:
| 识别号|值1|时间戳|性别|年龄|
| - ------|- ------|- ------|- ------|- ------|
| 1个|五十|2022年1月1日12时00分|米|七|
| 1个|八十|2022年1月1日12时30分|米|七|
| 1个|六十五|2022年1月1日13时00分|米|七|
| 第二章|六十五|2022年1月1日12:02:00|f级|八个|
| 第二章|八十三|2022年1月1日12时22分|f级|八个|
| 第二章|六十三|2022年1月1日12时42分|f级|八个|
我的期望:
| 识别号|值1|时间戳|性别|年龄|
| - ------|- ------|- ------|- ------|- ------|
| 1个|五十|2022年1月1日12时00分|米|七|
| 1个|钠氮|2022年1月1日12:02:00|米|七|
| 1个|钠氮|2022年1月1日12时22分|米|七|
| 1个|八十|2022年1月1日12时30分|米|七|
| 1个|钠氮|2022年1月1日12时42分|米|七|
| 1个|六十五|2022年1月1日13时00分|米|七|
| 第二章|钠氮|2022年1月1日12时00分|f级|八个|
| 第二章|六十五|2022年1月1日12:02:00|f级|八个|
| 第二章|八十三|2022年1月1日12时22分|f级|八个|
| 第二章|钠氮|2022年1月1日12时30分|f级|八个|
| 第二章|六十三|2022年1月1日12时42分|f级|八个|
| 第二章|钠氮|2022年1月1日13时00分|f级|八个|

x33g5p2x

x33g5p2x1#

你可以把你的任务重新想象成:根据 Dataframe 中存在的所有日期,将缺失日期添加到每个唯一的ID中,并在结果中填写NaNs。
例如,这可以通过使用经由多索引重新索引然后填充结果NaN s的一些魔术来实现:

data = {'ID': [1, 1, 1, 2, 2, 2],
        'timestamp': ['2022-01-01 12:00:00', '2022-01-01 13:00:00', '2022-01-01 18:00:00',
                      '2022-01-01 12:02:00', '2022-01-01 13:02:00', '2022-01-01 18:02:00'],
        'value1': [10, 20, 30, 40, 50, 60],
        'gender': ['M', 'M', 'F', 'F', 'F', 'M'],
        'age': [20, 25, 30, 35, 40, 45]}
df = pd.DataFrame(data)

# cross apply to build index 
cross = df[['ID']].drop_duplicates().merge(df[['timestamp']].drop_duplicates(), how = 'cross')
multiIdx = pd.MultiIndex.from_frame(cross)

# "add" missing rows
df = df.set_index(['ID', 'timestamp']) \
        .reindex(multiIdx, fill_value=np.nan) \
        .reset_index() \
        .sort_values(by=['ID', 'timestamp'], ignore_index=True)

# fill NaNs
df[['gender', 'age']] = df.groupby('ID')[['gender', 'age']].ffill().bfill()

统一采购司

如果你有非唯一的条目(基于ID + timestamp对),你可以使用左merge

cross = ...
df = cross.merge(df, on=['ID', 'timestamp'], how='left').sort_values(by=['ID', 'timestamp'],ignore_index=True)
df[['gender', 'age']] = df.groupby('ID')[['gender', 'age']].ffill().bfill()

相关问题