我有一个数据帧,它包含一个包含编码值和记录日期(例如(a,1((的序列。我的目标是检查编码值X和Y。如果它们发生在同一天,请从序列中删除Y值。
ID Sequence
1 [(A,1), (B,1), (X,2), (Y,2), (Y,3)]
2 [(C,1), (X,2), (Y,2), (Z,2)]
3 [(C,1), (D,2), (X,3), (Y,3),(Z,3)]
我期待的结果是:
ID Sequence
1 [(A,1), (B,1), (X,2), (Y,3)]
2 [(C,1), (X,2), (Z,2)]
3 [(C,1), (D,2), (X,3), (Z,3)]
有没有什么方法可以写一个函数来得到这些结果?如有任何帮助,我们将不胜感激。
您可以在元组中的第1个索引(第2个项(上检查集合成员身份(这对于此类用例来说非常快(,如果第一个值在X或Y中,如果第二个项已经存在,则不会附加列表,然后将此函数与df.apply
一起使用
def fun(l):
s = set()
lst = []
for i in l:
if i[0] in ('X','Y'):
if i[1] not in s:
s.add(i[1])
lst.append(i)
else:
lst.append(i)
return lst
df['Sequence'].apply(fun) # df['Sequence']=df['Sequence'].apply(fun) assign back
0 [(A, 1), (B, 1), (X, 2), (Y, 3)]
1 [(C, 1), (X, 2), (Z, 2)]
2 [(C, 1), (D, 2), (X, 3), (Z, 3)]
Name: Sequence, dtype: object
您可以使用itertools.groupby((将同一天分组到同一组,然后过滤掉同一组中的Y
。
最后使用itertools.chain((来压平列表。
import itertools
def remove_y(lst):
res = []
for key, values in itertools.groupby(lst, key=lambda x: x[1]):
values = list(values)
if len(values) > 1:
res.append([value for value in values if not 'Y' in value])
else:
res.append(values)
return list(itertools.chain(*res))
df['B'] = df['B'].apply(remove_y)
# print(df)
ID B
0 1 [(A, 1), (B, 1), (X, 2), (Y, 3)]
1 2 [(C, 1), (X, 2), (Z, 2)]
2 3 [(C, 1), (D, 2), (X, 3), (Z, 3)]