簡體   English   中英

在熊貓中尋找部分匹配並將值提取到新列

[英]look for partial match in pandas and extract value to new column

我有一個名為 df1 的數據框:

d = {'letter':['R','V','Q','M','F','K'], 'info1':['K:2.3','T:1.3','L:2.4','B:7.4','S:2.3','K:4.4'], 'info2':['R:3.2','N:2.1','B:0.3','T:0.9','J:0.003','S:1.223'], 'info3':['X:45','V:32.4','H:0.04','M:3.34','T:2.2','T:3.456'], 'info4':['A:1.7','Z:1.2345','T:9.5','O:3,2','J:3.334','G:345']}

df1 = pd.DataFrame(d)

df1:

  letter info1  info2   info3   info4
0   R   K:2.3   R:3.2   X:45    A:1.7
1   V   T:1.3   N:2.1   V:32.4  Z:1.2345
2   Q   L:2.4   B:0.3   H:0.04  T:9.5
3   M   B:7.4   T:0.9   M:3.34  O:3,2
4   F   S:2.3   J:0.003 T:2.2   J:3.334
5   K   K:4.4   S:1.223 T:3.456 G:345

我想將“字母”列中的字符串與該字符串在同一行上的出現部分匹配,並將匹配項放入新列中。 如果同一行沒有匹配項,那么我只想放置 NaN。

期望的輸出:

    letter   info1   info2   info3   info4     new
0      R     K:2.3   R:3.2   X:45    A:1.7     R:3.2
1      V     T:1.3   N:2.1   V:32.4  Z:1.2345  V:32.4
2      Q     L:2.4   B:0.3   H:0.04  T:9.5     NaN
3      M     B:7.4   T:0.9   M:3.34  O:3,2     M:3.34
4      F     S:2.3   J:0.003 T:2.2   J:3.334   NaN
5      K     K:4.4   S:1.223 T:3.456 G:345     K:4.4 

我最初嘗試創建一個面具,但沒有奏效。

df1['new'] = df1.drop("letter", 1).isin(df1["letter"]).any(1)

任何想法都會很棒

將您的數據堆疊成列格式,以便您可以按列操作。 然后子集到值匹配的地方。

>>> s = df1.set_index('letter').stack()
>>> s[s.index.get_level_values(0) == s.str[0]]
letter       
R       info2     R:3.2
V       info3    V:32.4
M       info3    M:3.34
K       info1     K:4.4
dtype: object

將此映射到原始數據框:

>>> s1 = _  # ie, the value coming out of the subset immediately above
>>> df1['letter'].map(s1.reset_index(level=1, drop=True))
0     R:3.2
1    V:32.4
2       NaN
3    M:3.34
4       NaN
5     K:4.4
Name: letter, dtype: object

然后將其作為df1['new']分配給您的數據框。 請注意,如果您的info#列中存在多個有效匹配項,則此方法還會引發有關多個匹配項的錯誤。 在我看來,Pandas 相對願意拋出錯誤(尤其是與 R 或 SAS 相比)對於避免靜默數據錯誤非常有用。 無論如何,如果重復是一個問題,只需刪除重復

這是一個單行解決方案,我們使用 subresult從每一行獲取第一個非空值

df1['new'] = df1.apply(lambda row: row[1:5][row.str.match(row['letter'])], axis=1).fillna(method='bfill', axis=1).iloc[:, 0]

0     R:3.2
1    V:32.4
2       NaN
3    M:3.34
4       NaN
5     K:4.4

這是另一種方式:

df['new'] = (df.loc[:,'info1':].where(df.loc[:,'info1':]
                          .applymap(lambda x: x[0])
                          .eq(df['letter'],axis=0))
 .ffill(axis=1).iloc[:,-1])

這就是我會做的:

df1['new'] = np.NaN    
for col in df1.columns.tolist()[1:-1]:
    df1.loc[df1[col].str[0] == df1['letter'], 'new'] = df1[col]

暫無
暫無

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

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