![](/img/trans.png)
[英]Check substring in dataframe column by referencing string position
[英]Get the position of a substring in a column of DataFrame using regex
我想使用正則表達式將字符串分解為Pandas DataFrame列。
樣本csv數據[ 更新 ]:
Data;Code;Temp;....
12 364 OPR 4 67474;;33;...
893 73 GDP hdj 747;;34;...
hr 777 hr9 GDP;;30;...
463 7g 448 OPR;;28;...
期望的情況:[ 更新 ]
Data | Code | Temp | ...
------------------------------------------------
12 364 | OPR 4 67474 | 33 | ...
893 73 | GDP hdj 747 | 34 | ...
hr 777 hr9 GDP | NaN | 30 | ...
463 7g 448 OPR | NaN | 28 | ...
正則表達式:
code = re.compile('\sOPR.?[^$]|\sGDP.?[^$]')
如果OPR
或GDP
不在字符串末尾,我只需要拆分即可。 我一直在尋找一種根據比賽位置進行分組的方法。 類似於: match.start()
)
我嘗試了類似的東西: df['data'].str.contains(code, regex=True)
和df['data'] = df['data'].str.extract(code, expand=True)
和str.find
似乎只適用於字符串,而不適用於re.Pattern
。 我沒有完成。
我對Pandas很陌生,所以請多多包涵。
我對python相當陌生,因此如果這不是一個好方法,則有人可以發表評論。 我的思路是接受輸入並逐行處理它。 刪除尾隨的半冒號,因為輸出中沒有它。 然后使用正則表達式,僅當其后接OPR或GDP並且不在行末時,才使用空格將行分隔。 如果這僅給出列表中的一項,則在列表后附加NaN以填充第二列。 然后我已經打印了格式。
import re
data_string="""12 364 OPR 4 67474;
893 73 GDP hdj 747;
hr 777 hr9 GDP;
463 7g 448 OPR;
"""
data_list=data_string.splitlines()
for data in data_list:
data_split=re.split("\s(?=(?:GDP|OPR)[^$])",data[:-1])
if len(data_split)==1: data_split.append("NaN")
print("%-20s|%-20s" % tuple(data_split))
輸出值
12 364 |OPR 4 67474
893 73 |GDP hdj 747
hr 777 hr9 GDP |NaN
463 7g 448 OPR |NaN
根據問題編輯和評論進行了更新
根據您對問題和評論的更新,可以嘗試以下操作。 我建議您對此進行測試並檢查是否存在任何極端情況,或者在執行更新之前添加驗證或條件檢查。
import pandas as pd
import re
source_data = {'data': ['12 364 OPR 4 67474', '893 73 GDP hdj 747', 'hr 777 hr9 GDP','463 7g 448 OPR'],
'code': [None, None, None, None],
'Temp': [33,34,30,28]
}
df = pd.DataFrame.from_dict(source_data)
print("Original df:")
print(df, "\n")
row_iter=df.iterrows()
for index,row in row_iter:
data=df.at[index,'data']
data_split=re.split("\s(?=(?:GDP|OPR)[^$])",data)
if len(data_split)==2:
df.at[index,'data']=data_split[0]
df.at[index,'code']=data_split[1]
print("Updated df:")
print(df)
輸出值
Original df:
data code Temp
0 12 364 OPR 4 67474 None 33
1 893 73 GDP hdj 747 None 34
2 hr 777 hr9 GDP None 30
3 463 7g 448 OPR None 28
Updated df:
data code Temp
0 12 364 OPR 4 67474 33
1 893 73 GDP hdj 747 34
2 hr 777 hr9 GDP None 30
3 463 7g 448 OPR None 28
因此,首先您必須檢查數據末尾是否具有GDP或OPR。 如果沒有,那么您可以使用分組的正則表達式來獲取所需的項目。 圓括號()中的內容代表一個組。 我使用最佳的語法?P命名了它們。
import re
data = ["12 364 OPR 4 67474;",
"893 73 GDP hdj 747;",
"hr 777 hr9 GDP;",
"463 7g 448 OPR;"]
for item in data:
# first check if it ends with GPR; or OPR;
if re.search("GDP;|OPR;$", item):
# as u specified it needs to be ignored
print(item)
else:
# now u can split into two parts - i am splitting in three but u can do use them however u like
splited_match_obj = re.search("(?P<Data>.+)(?P<Value>OPR|GDP)(?P<Code>.+)", item)
print(splited_match_obj["Data"], splited_match_obj["Value"], splited_match_obj["Code"] )
可以說這是您的數據框,
Data Temp
0 12 364 OPR 4 67474 33
1 893 73 GDP hdj 747 34
2 hr 777 hr9 GDP 30
3 463 7g 448 OPR 28
您可以根據條件將提取與多個捕獲組一起使用
df1[['Data', 'Code']] = df.loc[~df['Data'].str.endswith(('OPR','GDP')), 'Data'].str.extract('(.*)([A-Z]{3} .*)')
df2[['Data', 'Code']] = df.loc[df['Data'].str.endswith(('OPR','GDP')), 'Data'].str.extract('(.*[OPR|GDP]$)(.*)')
df[['Data', 'Code']] = pd.concat([df1,df2])
Data Temp Code
0 12 364 33 OPR 4 67474
1 893 73 34 GDP hdj 747
2 hr 777 hr9 GDP 30
3 463 7g 448 OPR 28
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.