簡體   English   中英

Pandas df 如何解析列值以使用正則表達式將字符串提取為 int

[英]Pandas df how to parse column value to extract string to int with regex

我有一個帶有 2 列的 Pandas df:

    name       Count_Relationship
0   allicin    DOWNREGULATE: 1
1   allicin    DOWNREGULATE: 2
2   allicin    UPREGULATE: 1 | DOWNREGULATE: 1
3   aspirin    UPREGULATE: 5 | DOWNREGULATE: 1
4   albuterol  DOWNREGULATE: 1
5   albuterol  UPREGULATE: 3

我只想過濾掉如果我按“名稱”分組並在“Count_Relationship”列中計算 DOWNREGULATE 數量大於 UPREGULATE 數量的行。 在這種情況下,大蒜素將具有 DOWREGULATE 1+2+1=4 和 UPREGULATE =1,因此 num_downregulate>num_upregulate,而在其余(阿司匹林,沙丁胺醇)中,情況並非如此。 我想返回這個過濾后的 df:

    name      Count_Relationship
0   allicin   DOWNREGULATE: 1
1   allicin   DOWNREGULATE: 2
2   allicin   UPREGULATE: 1 | DOWNREGULATE: 1

Count_Relationship 列是一個字符串,因此我必須解析字符串的數字部分並將其轉換為 int。

我試過這個:

    import pandas as pd

    data = {'name': ['allicin', 'allicin', 'allicin', 'aspirin', 'albuterol', 'albuterol'],
    'Count_Relationship': ['DOWNREGULATE: 1', 'DOWNREGULATE: 2', 'UPREGULATE: 1 | DOWNREGULATE: 1', 'UPREGULATE: 5 | DOWNREGULATE: 1', 'DOWNREGULATE: 1' , 'UPREGULATE: 3']
    }

    df = pd.DataFrame(data)

    substances = df["name"].tolist()
    substances = list(set(substances)) # to get the unique names

    result_substances = []
    
    for substance in (substances):
        try:
            numberOfdownregulate = df[(df["name"] == substance) & (\
            (df["Count_Relationship"].str.match(pat = '("DOWNREGULATE:"([0-9]))')).values[0].astype(int)        
        except:
            pass
        try:    
            numberOfupregulate = df[(df["name"] == substance) & (\
            (df["Count_Relationship"].str.match(pat = '("UPREGULATE:"([0-9]))')).values[0].astype(int)
        except:
            pass
    
        result = numberOfdownregulate - numberOfupregulate
        
        if result > 0:
            result_substances.append(substance)


    df_filtered = df[df["name"].isin(result_substances)]

但是我在我的正則表達式所在的 numberOfdownregulate 行出現語法錯誤。 如何修復算法? 非常感謝

您可以提取信息,比較上下,並構建一個掩碼來選擇數據:

drugs = (df.join(df['Count_Relationship'].str.extractall('(?P<down>(?<=DOWNREGULATE: )\d+)|(?P<up>(?<=UPREGULATE: )\d+)')
                   .groupby(level=0).first().fillna(0).astype(int)
                 )
           .groupby('name').agg({'down': 'sum', 'up': 'sum'})
           .query('down >= up')
           .index
        )

df[df['name'].isin(drugs)]

輸出:

      name               Count_Relationship
0  allicin                  DOWNREGULATE: 1
1  allicin                  DOWNREGULATE: 2
2  allicin  UPREGULATE: 1 | DOWNREGULATE: 1

我建議將 DOWNREGULATE 和 UPREGULATE 值提取到不同的列中,然后應用按名稱分組的值的總和並檢查哪個更大。

下面的示例創建了一個名為UP_gt_DOWN的附加布爾列,字面上 UPREGULATE 大於 DOWNREGULATE:

df['UPREGULATE'] = df['Count_Relationship'].str.extract(r"UPREGULATE: (\d*)").fillna(0).astype(int)
df['DOWNREGULATE'] = df['Count_Relationship'].str.extract(r"DOWNREGULATE: (\d*)").fillna(0).astype(int)

summed_df = df.groupby('name').sum()
summed_df['UP_gt_DOWN'] = summed_df['UPREGULATE'] > summed_df['DOWNREGULATE']
print(summed_df)

# Output
#            UPREGULATE  DOWNREGULATE  UP_gt_DOWN
# name                                           
# albuterol           3             1        True
# allicin             1             4       False
# aspirin             5             1        True

filtered_drugs = summed_df[~summed_df['UP_gt_DOWN']].index
print(df[df['name'].isin(filtered_drugs)])

# Output
#       name               Count_Relationship  UPREGULATE  DOWNREGULATE
# 0  allicin                  DOWNREGULATE: 1           0             1
# 1  allicin                  DOWNREGULATE: 2           0             2
# 2  allicin  UPREGULATE: 1 | DOWNREGULATE: 1           1             1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM