您好我有两个DataFrame,如下所示
DF1
Alpha | Numeric | Special
and | 1 | @
or | 2 | #
lol ok | 4 | &
DF2 with single column
Content
boy or girl
school @ morn
pyc LoL ok student
Chandra
我想搜索DF1中的任何列是否包含DF2的内容列中的任何关键字,并且输出应该是新的DF
`df11 = (df1.unstack()
.reset_index(level=2,drop=True)
.rename_axis(('col_order','col_name'))
.dropna()
.reset_index(name='val_low'))
df22 = (df2['Content'].str.split(expand=True)
.stack()
.rename('val')
.reset_index(level=1,drop=True)
.rename_axis('idx')
.reset_index())`
df22['val_low'] = df22['val'].str.lower()
df = (pd.merge(df22, df11, on='val_low', how='left')
.dropna(subset=['col_name'])
.sort_values(['idx','col_order'])
.drop_duplicates(['idx']))
df = (pd.concat([df2, df.set_index('idx')], axis=1)
.fillna({'col_name':'Other'})[['val','col_name','Content']])
但它没有考虑lol ok之间的空格
expected_output_DF
val col_name Content
0 or Alpha boy or girl
1 @ Special school @ morn
2 lol ok Alpha pyc LoL ok student
3 NaN Other Chandra
有人用这个帮助我
答案 0 :(得分:2)
融合数据帧1并将其转换为dict。然后根据数据帧2中的模式匹配获得的密钥得到dict的值,即
vals = df.melt()
di = dict(zip(vals['value'],vals['variable']))
# {'or': 'Alpha', 1: 'Numeric', 2: 'Numeric', 'and': 'Alpha', 4: 'Numeric', '@': 'Special', '#': 'Special', '&': 'Special', 'Special': 'new', 'Alpha': 'new', 'lol ok': 'Alpha'}
#Create a regex pattern based on dict keys.
pat = '|'.join(r"\s{}\s".format(x) for x in di.keys())
#Find the words that match the pattern
df2['val'] = df2['Content'].str.lower().str.findall(pat).apply(lambda x : x[0].strip() if len(x)>=1 else np.nan)
# Map the values with di and fill nan with other.
df2['new'] = df2['val'].map(di).fillna('other')
Ouptut:
Content new val 0 boy or girl Alpha or 1 school @ morn Special @ 2 pyc LoL ok student Alpha lol ok 3 Chandra other NaN
答案 1 :(得分:1)
使用str.cat
+ str.extract
。然后,使用map
作为列名,并使用pd.concat
加入。
i = df.stack().astype(str)
j = i.reset_index(level=0, drop=1)
m = dict(zip(j.values, j.index))
v = i.str.cat(sep='|')
df2['val'] = df2.Content.str.extract(r'\s(' + v + r')\s', flags=re.I, expand=False)
df2['col_name'] = df2['val'].str.lower().map(m).fillna('Other')
df2
Content val col_name
0 boy or girl or Alpha
1 school @ morn @ Special
2 pyc LoL ok student LoL ok Alpha
3 Chandra NaN Other
<强>详情
i
和j
是设置变量以创建映射m
是值到列名的映射v
是发送到str.extract
以进行关键字提取的正则表达式模式。我使用re.I
忽略案例map
+ fillna
通过m
v
'and|1|@|or|2|#|lol ok|4|&'
m
{'#': 'Special',
'&': 'Special',
'1': 'Numeric',
'2': 'Numeric',
'4': 'Numeric',
'@': 'Special',
'and': 'Alpha',
'lol ok': 'Alpha',
'or': 'Alpha'}
df['val']
0 or
1 @
2 LoL ok
3 NaN
Name: val, dtype: object
df['col_name']
0 Alpha
1 Special
2 Alpha
3 Other
Name: col_name, dtype: object