Новое в Python. Я родом из мира SQL, где я привык выполнять запросы и применять их. Удобно взять список вещей, получить их количество, а затем использовать подмножество этого количества (например, 5 лучших) и применить его к другим данным. С Python/Pandas я до сих пор не совсем понял процесс. В качестве примера:
Простой набор данных:
`import pandas as pd
dataset = (
[1,2,3,4,5,6],
[1,None,3,4,5,6],
[1,None,3,4,5,6],
[1,2,None,4,5,6],
[1,None,3,None,5,6],
[1,2,None,4,5,6],
[1,None,3,None,5,6],
[1,2,3,4,5,None],
[1,2,3,4,5,None]
)
df = pd.DataFrame(dataset, columns=['A','B','C','D','E','F'])`
Затем создайте фрейм данных, чтобы найти NaN:
nan_df = df.isna()
Затем посчитайте экземпляры каждой строки:
grouped_nan = nan_df.groupby(['A','B', 'C', 'D','E', 'F'], sort=True).value_counts()
Исходный набор, над которым я работал, содержал около 200 строк. Этот упрощенный пример дает следующее:
A B C D E F
False False False False False False 1
True 2
True False False False 2
True False False False False 2
True False False 2
Name: count, dtype: int64
Здесь у меня возникают проблемы. То, что я хочу сделать, лучше всего делать в Dataframe (выше — серия). Следующее делает его DataFrame:
grouped_nan_df = grouped_nan.to_frame()
Но последний столбец (счетчик) не включается так, как я могу. Я это вижу, но ничего не могу с этим поделать.
Если я попытаюсь сослаться на столбец со счетчиками, он его не распознает.
Если я попытаюсь переименовать этот последний столбец, это не сработает:
`grouped_nan_df.rename(columns = {grouped_nan_df.columns[5]:"new_count"}, inplace=True)`
выдает ошибку «индекс 5 выходит за пределы оси 0 с размером 1».
В конце мне нужен DataFrame, включающий счетчики. Есть ли способ туда добраться?
Любая помощь приветствуется!
Энди
@mozway Спасибо! По какой-то причине, когда я делаю это, а затем пытаюсь вызвать столбец, хотя он type() как фрейм данных, я получаю сообщение об ошибке, в котором говорится, что объект DataFrame не может быть вызван. Ответ ниже аналогичен тому, что вы предложили. но использует размер, который я затем могу назвать. Я не знаю, в чем разница, кроме этого.
вам скорее всего не нужен groupby
. Я считаю, что ваша ошибка связана с чем-то неправильным, что вы сделали в коде, который здесь не показан. Этого не должно случиться. Попробуйте запустить новую оболочку/ноутбук со своим минимальным примером. Смотрите мой ответ ниже. Примечание. value_counts
следует отдавать предпочтение groupby.size
, поскольку он более эффективен.
IIUC, вы можете просто использовать groupby
с as_index=False
, а затем взять размер группы :
out = nan_df.groupby(['A','B', 'C', 'D','E', 'F'], as_index=False).size()
Выход:
A B C D E F size
0 False False False False False False 1
1 False False False False False True 2
2 False False True False False False 2
3 False True False False False False 2
4 False True False True False False 2
Спасибо! Я точно не знаю, почему это становится фреймом данных, а не серией, как раньше, но он работает и возвращается как фрейм данных. Я пытался проголосовать за ответ, но мне это не позволило (у меня недостаточно репутации) — извините.
@AndyB as_index=False
добавляет в результат столбцы группировки, поэтому вы получаете фрейм данных, а не серию, индексированную этими столбцами.
Достаточно просто добавить reset_index
:
Кроме того, поскольку вы используете все столбцы, вам не нужно groupby
:
import pandas as pd
dataset = (
[1,2,3,4,5,6],
[1,None,3,4,5,6],
[1,None,3,4,5,6],
[1,2,None,4,5,6],
[1,None,3,None,5,6],
[1,2,None,4,5,6],
[1,None,3,None,5,6],
[1,2,3,4,5,None],
[1,2,3,4,5,None]
)
df = pd.DataFrame(dataset, columns=['A','B','C','D','E','F'])
nan_df = df.isna()
grouped_nan = (nan_df[['A','B', 'C', 'D','E', 'F']]
.value_counts()
.reset_index()
)
print(grouped_nan)
Или просто:
nan_df = df.isna()
grouped_nan = nan_df.value_counts().reset_index()
print(grouped_nan)
A B C D E F count
0 False False False False False False 1
1 False False False False False True 2
2 False False True False False False 2
3 False True False False False False 2
4 False True False True False False 2
Я запустил timeit для обоих решений, и время на моей машине практически одинаковое.
@Ник, интересно, я почти уверен, что раньше было быстрее. Я только что проверил исходный код и обнаружил, что value_counts
внутренне использует groupby.size. Я не знаю, то ли у меня подвела память, то ли код был улучшен;)
Одно можно сказать наверняка: groupby
+value_counts
не нужен!
Интересный. Таким образом, они по сути запускают один и тот же код, а значит, и в одно и то же время. Однако, как вы говорите, groupby
в этом случае совершенно излишен.
@Ник Series.value_counts
быстрее , что groupby.size
(он использует другой алгоритм), это действительно не относится к DataFrames.
Опять интересно. Итак, теперь вопрос в том, почему фреймы данных не используют более быстрый алгоритм...
Спасибо вам обоим. Здесь кое-что узнал! Я думаю, что SQL заставил меня подумать, что группировка необходима.
Просто
reset_index()
послеvalue_counts
.