我确实有一个包含两列的数据框:date和bill_id。日期列中的日期范围是从 01-01-2017 到 30-12-2017 的一年。有 1000 个独特的bill_ids. 每个bill_id可能在bill_id列中至少出现一次。结果是一个大小为:2 列,1000000 行的 DataFrame...
dt |bill_id
01-01-2017 bill_1
01-01-2017 bill_2
02-01-2017 bill_1
02-01-2017 bill_3
03-01-2017 bill_4
03-01-2017 bill_4
因此,某些 name_id 可能会在特定日期出现,而其他则不会。
我想要实现的是一种格式的数据框,因此所有唯一的 bill_id 都是列,所有唯一的日期都是行,并且每个 bill_id 具有 0 或 1 或 2 对应的日期值,其中 0 = 尚未出现在该日期,1 出现在那个日期,2 没有出现在那个日期,但在之前就已经存在了,例如
如果 bill_id 存在于 02-01-2017,那么它将在 01-01-2017 为 0,在 02-01-2017 为 1,在 03-01-2017 为 2,在所有后续日期为 2。
我用几个步骤完成了,但代码没有扩展,因为它很慢:
def map_values(row, df_z, c):
subs = df_z[[c, 'bill_id', 'date']].loc[df_z['date'] == row['dt']]
if c not in subs['bill_id']:
row[c] = max(subs[c].tolist())
else:
val = df_z[c].loc[(df_z['date'] == row['dt']) & (df_z['bill_id'] == c)].values
assert len(val) == 1
row[c] = val[0]
return row
def map_to_one(x):
bills_x = x['bill_id'].tolist()
for b in bills_x:
try:
x[b].loc[x['bill_id'] == b] = 1
except:
pass
return x
def replace_val(df_groupped, col):
mask = df_groupped.loc[df_groupped['bill_id'] == col].index[df_groupped[col].loc[df_groupped['bill_id'] == col] == 1]
min_dt = df_groupped.iloc[min(mask)]['date']
max_dt = df_groupped.iloc[max(mask)]['date']
df_groupped[col].loc[(df_groupped['date'] < min_dt)] = 0
df_groupped[col].loc[(df_groupped['date'] >= min_dt) & (df_groupped['date'] <= max_dt)] = 1
df_groupped[col].loc[(df_groupped['date'] > max_dt)] = 2
return df_groupped
def reduce_cols(row):
col_id = row['bill_id']
row['val'] = row[col_id]
return row
df = df.sort_values(by='date')
df = df[pd.notnull(df['bill_id'])]
bills = list(set(df['bill_id'].tolist()))
编辑:
Joe 的回答很好,但我决定改用其他选项:
获取 date.min() 和 date.max()
df_groupped = groupby bill_id
df_groupped 应用函数,其中我检查每组 date_x.min() 和 date_x.max() 并将 date.min() 与 date_x.min() 和 date.max() 与 date_x.max() 进行比较等等我知道 0、1 和 2 在哪里的方式:)
相关分类