问题描述
我希望有人能帮助我。
我有 3 个额外的列名列表,其中包括列的原始名称(即出现在问号之前的字符串(请参阅列名列表)
我需要根据匹配 3 个列表中存在的列名的第一部分,将 df 数据帧子集划分为 3 个单独的数据帧。底部的预期输出。
它必须在列表(或一些程序化的)中,因为我有很多这样的列。我尝试过模式匹配,但因为有些名称非常相似,所以它们匹配多个列表。
先谢谢你!
示例数据
df = {'id': ['1','2','3','4'],'ab? op': ['green','red','blue','None'],'ab? 1': ['red','yellow','None','cd': ['L','XL','M','L'],'efab? cba' : ['husband','wife','husband','efab? 1':['son','grandparent','son','efab? 2':['None','fab? 4':['9','10','5','3'],'fab? po':['England','Scotland','Wales','NA'] }
df = pd.DataFrame(df,columns = ['id','ab? op','ab? 1','cd','efab? cba','efab? 1','efab? 2','fab? 4','fab? po'])
其他 3 个数据框中的列名列表
df1_lst = ['ab','cd']
df2_lst = ['efab']
df3_lst = ['fab']
期望输出
df1 = ['ab? op','cd']
df2 = ['efab? cba','efab? 2']
df3 = ['fab? 4','fab? po']
解决方法
您可以为每个 df 列表形成一个动态正则表达式:
df_lists = [df1_lst,df2_lst,df3_lst]
result = [df.filter(regex=fr"\b({'|'.join(names)})\??") for names in df_lists]
例如,对于第一个列表,regex 是 \b(ab|cd)\??
即查找 ab
或 cd
但它们应该从左侧独立({{1 }}) 之后可能会有一个可选的 \b
。
所需的条目在 ?
列表中,例如
result
,
按 ?
拆分列名,保留第一部分并检查它们是否在列表中:
df1 = df.loc[:,df.columns.str.split('?').str[0].isin(df1_lst)]
df2 = df.loc[:,df.columns.str.split('?').str[0].isin(df2_lst)]
df3 = df.loc[:,df.columns.str.split('?').str[0].isin(df3_lst)]
>>> df1
ab? op ab? 1 cd
0 green red L
1 red yellow XL
2 blue None M
3 None None L
>>> df2
efab? cba efab? 1 efab? 2
0 husband son None
1 wife grandparent son
2 husband son None
3 None None None
>>> df3
fab? 4 fab? po
0 9 England
1 10 Scotland
2 5 Wales
3 3 NA