Как выполнить поиск в строках, чтобы проверить, содержит ли строка значение, и извлечь только этот конкретный столбец

#python #pandas #dataframe

#python #pandas #dataframe

Вопрос:

Я пытаюсь выполнить итерацию по строкам фрейма данных, чтобы найти, является ли значение TRUE. Фрейм данных выглядит следующим образом:

 Mass    900.5    901.5    902.5    1000.5    1001.5   
Height  100      200      300      400       500
mass
901.4  FALSE     TRUE     FALSE    FALSE     FALSE
903.5  FALSE     FALSE    FALSE    FALSE     FALSE
1001.4 FALSE     FALSE    FALSE    FALSE     TRUE
  

Как вы можете видеть, строка может иметь ‘TRUE’ или может иметь только ‘FALSE’. Я хочу выполнить итерацию по строкам для 1-го столбца после mass и выполнить поиск, если в строке нет ‘TRUE’. Если в строке нет ‘TRUE’, то я хочу присвоить значение для этой конкретной строки как пустое пространство (что эквивалентно None в python, я полагаю). Мой текущий код извлекает «ИСТИННЫЕ» значения и собирает соответствующие значения высоты.

Например, приведенный выше фрейм данных после использования моего кода выдаст:

текущие результаты:

 Mass    Height
901.4   200
1001.4  500
  

код 1:

 matches = pd.DataFrame(index=pickuplist['mass'],
                        columns=df.set_index(list(df.columns)).index,
                        dtype=bool)
  

К вашему сведению, код 1 — это то место, где изначально определено соответствие df.

код 2:

 for index, exp_mass, intensity in df.itertuples():
    matches[exp_mass] = abs(matches.index - exp_mass)/matches.index < ppm/1e6
  

Приведенная выше строка создает пример фрейма данных после получения значений на основе допуска ppm.

код 3:

 list = matches.any().reset_index(name='a')[matches.any().values]
  

Я полагаю, что приведенная выше строка извлекает значения массы и высоты (таблица текущих результатов).

Я пытался использовать if / iloc и другие, чтобы посмотреть, могу ли я присвоить None конкретной строке, но не сработало. Ожидаемые результаты должны быть:

Список:

 Mass    Height
901.4   200
903.5   
1001.4  500
  

(Правка1)
Я попытался использовать предложения первого ответа, и это дало мне что-то вроде:

     Height
0   TRUE
1   TRUE
2   TRUE
  

Возможно, форматы фреймов данных отличаются. Также нет значений False или NaN. Пожалуйста, обратите внимание, что между строкой Height и строкой 901.4 есть пустая строка.

(Edit2) Попытался использовать предложения из второго ответа, и это дало мне:

     Mass    Height
0   901.4   (901.4, 200)
1   903.5   (903.5, 518)
2   1001.4  (1001.4, 500)
  

Значение высоты строки index 1 должно быть пустым, но по какой-то причине получило случайное значение. При просмотре импортированных данных, которые поступают в matches dataframe, значение 518, по-видимому, является первым значением высоты данных.

Исходные данные, которые передаются в matches dataframe, выглядят следующим образом:

 Mass    Height
899.1   518
900.5   100
901.5   200
902.5   300
950.5   400
1000.5  400
1001.5  500
  

и так далее.

Комментарии:

1. Что произойдет, если несколько True s на строки?

2. В строке не должно быть нескольких значений True, поскольку каждая строка может иметь либо none, либо одно значение mass pickup.

Ответ №1:

Если требуется первое True значение, если оно существует, иначе NaN сначала удалите первый уровень MultiIndex by DataFrame.droplevel , затем добавьте новый столбец с именем NaN для совпадения строк только с False и в последний раз используйте DataFrame.idxmax для первого True столбца в строках:

 df1 = df.droplevel(0, axis=1)
df1[np.nan] = True
df2 = df1.idxmax(axis=1).rename_axis('Mass').reset_index(name='Height')
print (df2)
     Mass Height
0   901.4    200
1   903.5    NaN
2  1001.4    500
  

Комментарии:

1. Попробовал ваши предложения. Пожалуйста, смотрите Edit2 моего поста для обновления.

2. @BongKyoSeo — Похоже, что используйте только df1.idxmax(axis=1) , затем получайте кортежи в выходных данных.

Ответ №2:

Вы можете сделать что-то вроде следующего, это не совсем чистый способ, но он будет работать для вас.

Я создаю df, подобный вашему результату:

     import pandas as pd
    df = pd.DataFrame(index = [901.4, 903.5, 1001.4],
                      columns=[100, 200, 300, 400, 500],
                      data=[[False, True, False, False, False],
                            [False, False, False, False, False],
                            [False, False, False, False, True]])
   df.index.name = 'mass'
   df.columns.name = 'Height'
  

Здесь я передам все строки и создам новый df с вашим правильным форматом:

     import numpy as np

    new_df = pd.DataFrame(columns = ['Height'])
    for index, row in df.iterrows():
        if not row.any():
            new_df.loc[index, 'Height'] = np.nan
        else:
            new_df.loc[index, 'Height'] = row.any()
  

Надеюсь, это поможет вам!

Комментарии:

1. Я попробовал ваши предложения. Пожалуйста, смотрите Edit1 моего поста для обновления. Спасибо!