Проверьте, что n-ое значение в DataFrame равно n-му символу в строке - PullRequest
1 голос
/ 03 марта 2020

У меня есть df:

df =
     c1  c2   c3   c4  c5
  0  K   6    nan  Y   V
  1  H   nan  g    5   nan
  2  U   B    g    Y   L

И строка

s = 'HKg5'

Я хочу вернуть строки, где s [0] = значение c1, s [1] = значение c2, ..... + в некоторых случаях, когда s [i] = nan.

Например, строка 1 в df выше совпадает со строкой

    row 1=
           c1  c2   c3   c4  c5
        1  H   nan  g    5   nan
                                                match=True,   regardless of s[1,4]=nan
     s   = H   K    g    5

А также длина строки - динамическая c, поэтому мои df cols go выше c10

Я использую df.apply, но не могу понять это ясно. Я хочу написать функцию для передачи в df.apply, одновременно передавая строку.

Спасибо за любую помощь!

Вывод ответа Криса

  df=  
        c1  c2  c3  c4  c5 
     0  K   6  NaN  Y   V
     1  H  NaN  g   5  NaN
     2  U   B   g   Y   L

  s = 'HKg5'
  s1 = pd.Series(list(s), index=[f'c{x+1}' for x in range(len(s))])
  df.loc[((df == s1) | (df.isna())).all(1)]

Вывод

  `c1  c2  c3  c4  c5`

1 Ответ

2 голосов
/ 03 марта 2020

Создайте помощника Series из вашей строки и используйте логические логики c для фильтрации:

s1 = pd.Series(list(s), index=[f'c{x+1}' for x in range(len(s))])

# print(s1)    
# c1    H
# c2    K
# c3    g
# c4    5
# dtype: object

Лог c равен df равно (==) этому значению ИЛИ (|) равно nan (isna)
Используйте all вдоль оси 1, чтобы получить строки, в которых все значения равны True

df.loc[((df == s1) | (df.isna())).all(1)]

[out]

  c1   c2 c3 c4   c5
1  H  NaN  g  5  NaN

Итак, в качестве функции вы можете сделать:

def df_match_string(frame, string):
    s1 = pd.Series(list(string), index=[f'c{x+1}' for x in range(len(string))])
    return ((frame == s1) | (frame.isna())).all(1)

df_match_string(df, s)

[out]

0    False
1     True
2    False
dtype: bool

Обновление

Я не могу воспроизвести вашу проблему с приведенным примером. Я предполагаю, что некоторые значения в вашем DataFrame могут иметь начальные / конечные пробелы?

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

for col in df:
    df[col] = df[col].str.strip()
...