Подсчет каждой строки путем исключения определенного слова с использованием фрейма данных Pandas

#python-3.x #pandas #dataframe

Вопрос:

У меня есть фрейм данных panda, который выглядит следующим образом:

 id    info_type1    pval1_1    pval2_1     info_type2    pval1_2    pval2_2    info_type3    pval1_3    pval2_3    

ione11    IT       void         0.05       void           1.0       void        IT     void    void    0.04            

ione77    IV       1.0         void       void           1.0       void        void     void    void    0.04            
 

Для каждой строки я пытаюсь подсчитать количество полей, в которых нет слова void. Подсчет не должен включать идентификатор поля (первое поле). Например, для первой строки у вас будет 5 полей со значениями, отличными от void, а в строке 2 будет 4 значения. поэтому в итоге я получу список идентификаторов с их значениями. Например:

 id            count 
ione11         5
ione77         4
 

Если я выполню итерацию с помощью df.iterrows(), я не смогу проверить все столбцы в строке. Как вы собираетесь это решить?

Заранее большое спасибо.

Ответ №1:

apply Примерьте ряды:

 df_ = pd.DataFrame()

df_['id'] = df['id']
df_['count'] = df.apply(lambda row: len(row[1:]) - row[1:].tolist().count('void'), axis=1)
 

Для подсчета void встречаемости в серии вы также можете использовать sum(row[1:].isin(['void'])) .

 print(df_)

    id     count
0  ione11      5
1  ione77      4
 

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

1. Хорошее решение, однако , когда я пытаюсь напечатать df_, он не включает идентификатор, только индекс, который не совпадает с идентификатором.

2. @Абиолог, ты видел мою другую print(df_.reset_index().rename(columns={'index': 'id'})) ?

3. Да, пробовал. Идентификатор-это не индекс, это другой столбец в фрейме данных. кроме того, подсчет не должен учитывать столбец идентификатора, поэтому подсчет не совсем правильный.

4. @aBiologist В вашем примере данных первая строка содержит 10 значений, в то время как другие имеют 11 значений. Это правильно?

5. @aBiologist я считаю 3 раза, они не одинаковой длины. Вы можете проверить это еще раз?

Ответ №2:

Я бы сделал это так, чтобы преобразовать void NaN и получить количество всех элементов, которые не NaNs используются notna() , и sum() вот так:

 df = pd.DataFrame({'id': {'ione11': 'IT', 'ione77': 'IV'}, 'info_type1': {'ione11': 'void', 'ione77': '1.0'}, 'pval1_1': {'ione11': '0.05', 'ione77': 'void'}, 'pval2_1': {'ione11': 'void', 'ione77': 'void'}, ' info_type2': {'ione11': 1.0, 'ione77': 1.0}, 'pval1_2': {'ione11': 'void', 'ione77': 'void'}, 'pval2_2': {'ione11': 'IT', 'ione77': 'void'}, 'info_type3': {'ione11': 'void', 'ione77': 'void'}, 'pval1_3': {'ione11': 'void', 'ione77': 'void'}, 'pval2_3': {'ione11': 0.04, 'ione77': 0.04}})
df = df.T.replace({'void' : np.nan}).notna().sum().reset_index().rename(columns={0: 'count', 'index': 'id'})
df
 

Выход:

     id      count
0   ione11      5
1   ione77      4
 

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

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

2. Нет, ты этого не сделаешь. Фрейм данных, который я использовал, выглядит точно так же, как ваш. Позвольте мне отредактировать его с помощью фрейма данных, который я использовал.

Ответ №3:

Вы можете сопоставить каждый элемент с целым числом, а затем суммировать строки.

 import numpy as np
import pandas as pd

df = pd.DataFrame([["it", "void", "1"], ["it", "void", "1"]])        
df = df.applymap(lambda x: 1 if x == 'void' else 0)
df = df.sum(axis = 1))
 

Ресурсы:

Ответ №4:

Вы можете суммировать логическую маску df != 'void' (игнорировать id , установив ее в качестве индекса).:

 df.set_index('id').ne('void').sum(axis=1).reset_index(name='count')

#        id  count
# 0  ione11      5
# 1  ione77      4