#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