Соответствие, если значение столбца в df является одним из значений другого столбца в том же кадре данных (построчно) - PullRequest
0 голосов
/ 30 ноября 2018

df

col1  col2
A      a|x|y
B      a|x|y
C      c|x|z
D      e|j|y

Моя цель - создать новый столбец с именем «status», чтобы увидеть, является ли запись в col1 одной из записей в col2 (разделенных каналом).вывод должен быть таким:

col1  col2     status
A      a|x|y   True
B      a|x|y   False
C      c|x|z   True
D      e|j|y   False

Мой код:

df["col1"]= df["col1"].str.lower()
df['status']=df['col1'].isin(df['col2']) 

Но это дает все записи в столбце 'status' как False

Пожалуйста, помогите мне с этим, пожалуйста!!!

Ответы [ 3 ]

0 голосов
/ 30 ноября 2018

Подобно этому ответу , вы можете использовать понимание списка.Предполагается, что ваши данные чистые, например, нулевые значения.

zipper = zip(df['col1'], df['col2'])
df['status'] = [i.casefold() in j.casefold().split('|') for i, j in zipper]

print(df)

  col1   col2 status
0    A  a|x|y   True
1    B  a|x|y  False
2    C  c|x|z   True
3    D  e|j|y  False
0 голосов
/ 30 ноября 2018

Возможно, вам следует сначала перенести ваш фрейм данных в формат, с которым проще работать.

Я предлагаю что-то вроде этого:

>>> df = pd.concat([df['col1'], df['col2'].str.upper().str.split('|', expand=True)], axis=1)                                                                                                             
>>> df                                                                                                                                                                                                   
  col1  0  1  2
0    A  A  X  Y
1    B  A  X  Y
2    C  C  X  Z
3    D  E  J  Y

Теперь вы можете сделать:

>>> df['status'] = df.apply(lambda s: s.duplicated().any(), axis=1)                                                                                                                                     
>>> df                                                                                                                                                                                                    
  col1  0  1  2  status
0    A  A  X  Y    True
1    B  A  X  Y   False
2    C  C  X  Z    True
3    D  E  J  Y   False

В этом решении предполагается, что индикаторы состояния, которые вы разделяете с помощью '|', уникальны, то есть вы не можете иметь что-то вроде 'x|x|x'.


Если вам не нравится предложениерассмотрим:

>>> df['status'] = df.apply(lambda row: row[0].lower() in row[1].split('|'), axis=1)                                                                                                                     
>>> df                                                                                                                                                                                                  
   col1   col2  status
0    A  a|x|y    True
1    B  a|x|y   False
2    C  c|x|z    True
3    D  e|j|y   False
0 голосов
/ 30 ноября 2018

get_dummies

df.col2.str.get_dummies().mul(pd.get_dummies(df.col1.str.lower())).sum(1).astype(bool)

0     True
1    False
2     True
3    False
dtype: bool

a = pd.get_dummies(df.col1.str.lower())
b = df.col2.str.get_dummies()
status = b.mul(a).sum(1).astype(bool)
df = df.assign(status=status)

df

  col1   col2  status
0    A  a|x|y    True
1    B  a|x|y   False
2    C  c|x|z    True
3    D  e|j|y   False

get_dummies и einsum

a = pd.get_dummies(df.col1.str.lower())
b = df.col2.str.get_dummies()
a, b = a.align(b, fill_value=0)
status = np.einsum('ij,ij->i', a, b).astype(bool)

df = df.assign(status=status)
df

  col1   col2  status
0    A  a|x|y    True
1    B  a|x|y   False
2    C  c|x|z    True
3    D  e|j|y   False
...