我有以下数据集:
column1
HL111
PG3939HL11
HL339PG
RC--HL--PG
我正在尝试编写执行以下操作的函数:
因此对于上面的示例,我的数组(第2步)将如下所示:
[HL]
[PG,HL]
[HL,PG]
[RC,HL,PG]
和我想要的最终输出(步骤4)如下所示:
desired_column
HL
PG
PG
RC
我有第2步的代码,它似乎工作正常
df['array_column'] = (df.column1.str.extractall('([A-Z]+)')
.unstack()
.values.tolist())
但是我不知道如何从这里到我的最终输出(步骤4)。
答案 0 :(得分:0)
这是使用apply
演示:
import re
import pandas as pd
def checkValue(value):
value = re.findall(r"[A-Z]{2}", value)
if (len(value) > 1) and ("HL" in value):
return [i for i in value if i != "HL"][0]
else:
return value[0]
df = pd.DataFrame({"column1": ["HL111", "PG3939HL11", "HL339PG", "RC--HL--PG"]})
print(df.column1.apply(checkValue))
输出:
0 HL
1 PG
2 PG
3 RC
Name: column1, dtype: object
答案 1 :(得分:0)
首先替换所有非字母,然后提取字母对,然后应用一些自定义逻辑从数组中提取必要的值,即可实现所需的目的:
>>> df['array_column'].str.replace('[^A-Z]+', '').str.findall('([A-Z]{2})').apply(lambda d: [''] if len(d) == 0 else d).apply(lambda x: 'HL' if len(x) == 1 and x[0] == 'HL' else [m for m in x if m != 'HL'][0])
0 HL
1 PG
2 PG
3 RC
Name: array_column, dtype: object
>>>
详细信息
.replace('[^A-Z]+', '')
-删除所有大写字母以外的字符.str.findall('([A-Z]{2})')
-提取字母对.apply(lambda d: [''] if len(d) == 0 else d)
将添加一个空项目.apply(lambda x: 'HL' if len(x) == 1 and x[0] == 'HL' else [m for m in x if m != 'HL'][0])
-自定义逻辑:如果列表长度为1并且等于HL
,请保留它,否则删除所有HL
并获取第一个元素答案 2 :(得分:0)
您可以执行类似的操作(或可能更优雅的操作),使您已经拥有一个相当不错的结构,可以在其中使用groupby来完成解决方案
def extract_relevant_str(grp):
ret_val = None
if "HL" in grp[0].tolist() and len(grp) == 1:
ret_val = "HL"
elif len(grp) >= 1:
ret_val = grp.loc[grp[0] != "HL", 0].iloc[0]
return ret_val
items = df.column1.str.extractall('([A-Z]+)')
items.reset_index().groupby("level_0").apply(extract_relevant_str)
输出:
level_0
0 HL
1 PG
2 PG
3 RC
dtype: object