我有一个DataFrame,例如:
tag1 other
0 a,c foo
1 b,c foo
2 d foo
3 a,a foo
其中的条目是以逗号分隔的字符串。
每个标签的定义字典,例如:
dict = {'a' : 'Apple',
'b' : 'Banana',
'c' : 'Carrot'}
我想要替换a
,b
和c
的定义,但要删除其中不存在该字典内容的行(即d
)。此外,我想确保没有重复项,例如示例数据集中的行索引3。
到目前为止我所拥有的:
df.tags = df.tags.str.split(',')
for index, row in df.iterrows():
names = []
for tag in row.tag1:
if tag == dict[tag]:
names.append(dict[tag])
else:
df.drop(df.index[index])
从那里我将用names
中的值替换原始列。要替换重复项,我想迭代数组并检查下一个值是否与下一个值匹配,如果是,则删除它。但是,这不起作用,我有点难过。所需的输出看起来像(使用unicode中的字符串):
tag1 other
0 ['Apple', 'Carrot'] foo
1 ['Banadn', 'Carrot'] foo
3 ['Apple'] foo
答案 0 :(得分:4)
我参加最长的一次班轮比赛
m = {
'a' : 'Apple',
'b' : 'Banana',
'c' : 'Carrot'
}
df.tag1.str.split(',', expand=True) \
.stack().map(m).groupby(level=0) \
.filter(lambda x: x.notnull().all()) \
.groupby(level=0).apply(lambda x: x.drop_duplicates().str.cat(sep=',')) \
.to_frame('tag1').join(df.other)
tag1 other
0 Apple,Carrot foo
1 Banana,Carrot foo
3 Apple foo
但严重的是,可能是一个更好的解决方案
a = np.core.defchararray.split(df.tag1.values.astype(str), ',')
lens = [len(s) for s in a]
b = np.concatenate(a)
c = [m.get(k, np.nan) for k in b]
i = df.index.values.repeat(lens)
s = pd.Series(c, i)
def proc(x):
if x.notnull().all():
return x.drop_duplicates().str.cat(sep=',')
s.groupby(level=0).apply(proc).dropna().to_frame('tag1').join(df.other)
tag1 other
0 Apple,Carrot foo
1 Banana,Carrot foo
3 Apple foo