Проверьте, равно ли какое-либо значение 0 в Python DataFrame

У меня есть файлы csv, например:

Time   Test Two Three Five Six Seven Eight Nine Ten Eleven Twelve Thirteen  Fifteen  Sixteen   
0       0   0    0    0   0     0    0     0   -0.3   0     0       100        0       0   
0.02    0   0    0    0   0     0    0     0  -0.1   0.05   0       99        28       0   
0.04    0   0    0    0   0     0    0     0  -0.15  0.05   0.9    99.6      28.7      0   
...

Мой код выглядит так:

list_of_dfs = [pandas.read_csv(filename) for filename in filenames]
for i in list_of_dfs:
    if any(x is 0 for x in i.Test):
        print("true")
    else:
        print("false")

Это показывает мне только ложь (даже i.Test всегда 0)

print(list_of_dfs[0].Test)

показывает

0      0
1      0
2      0
3      0
4      0
5      0
6      0
7      0
8      0
9      0
10     0
..
655    0
656    0
657    0
658    0
659    0
660    0
661    0
662    0
663    0
664    0
665    0
Name: Test, Length: 666, dtype: int64

Не должно быть

any(x is 0 for x in i.Test) 

всегда верно, как и в каждом i.Test минимум один "0" (поскольку они содержат только нули)

В чем моя ошибка?

Используйте x==0 вместо x is 0

rafaelc 12.06.2018 23:37
i.Test не является типом данных int. проверить по print(i.Test)
Morse 12.06.2018 23:38

Еще лучше транслировать тест по серии, а не зацикливаться в выражении генератора: df.i == 0 - это серия логических значений, а (df.i == 0).any() истинно, если любое из этих значений истинно. Или, поскольку 0 неверно, а все остальные числа верны, вы можете использовать not df.i.all(), чтобы получить тот же эффект более эффективно (но, вероятно, менее читабельно).

abarnert 12.06.2018 23:43

с кодом минимальный воспроизводимый пример для одного файла с разделителем ',' я не смог воспроизвести проблему. Приведенный выше код возвращает true, если все значения Test являются int, а не float и не str.

Morse 12.06.2018 23:54

@Prateek Я проверил, что list_of_dfs [0] .Test - это тип данных int64. I.Test в этом случае должен быть таким же. Я пытаюсь привести минимальный нерабочий пример. Но было бы слишком много загружать тысячи файлов csv

ChrizZlyBear 13.06.2018 00:06

@RafaelC x == 0 исправил проблему. Большое спасибо

ChrizZlyBear 13.06.2018 00:27

@abarnert (i.Test == 0).any() дал мне те же результаты, что и any(x == 0 for x in i.Test). Однако я могу представить, что ваш метод более эффективен. Могу ли я также вычислить среднее значение DataFrame? Как среднее из тринадцати?

ChrizZlyBear 13.06.2018 00:34

@ChrizZlyBear Да. Под обложками каждая серия (столбец) представляет собой массив numpy, что означает, что вы можете получить все преимущества простоты и производительности от использования numpy на них. (Предполагая, что это числовые столбцы, то есть; если у них есть dtype=object, вы не получите большого преимущества в производительности, а для некоторых сложных типов часто проще использовать функции высокого уровня pandas или даже apply / map, чем раскрывать to numpy.) Таким образом, вы можете получить среднее значение, вызвав на нем sum(), а затем разделив на len, или используя ... Я думаю, что это scipy.stats.mean(i.Thirteen), но вы можете найти его.

abarnert 13.06.2018 00:40

Между тем, если вы хотите понять разницу между is и ==, страницу документации и / или соответствующие вопросы SO может быть сложно найти, поэтому дайте мне знать, и я найду ссылку. Но краткий ответ заключается в том, что a is b верен только в том случае, если a и b являются тот же объект, а объект pandas int64 никогда не будет тем же объектом, что и встроенный объект int, в то время как == проверяет, имеют ли они тот же значение, являются ли они один и тот же объект или два разных объекта, которые оказываются равными. Вам почти никогда не понадобится is с числами, но вы часто хотите его со специальными одноэлементными значениями, такими как None.

abarnert 13.06.2018 00:45

@abarnert Я только что понял, как много я могу сделать с помощью этого метода. Не только в этом случае. Но это сократило 4 других комплекса петель в один вкладыш. и numpy / SciPy даже не проще. Думаю, они тоже намного эффективнее. Это мне тоже очень помогло.

ChrizZlyBear 13.06.2018 01:04
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
10
2 962
1

Ответы 1

Постановка проблемы, если я правильно понимаю, состоит в том, чтобы вернуть значение для каждого фрейма данных в списке в зависимости от того, существует ли 0 в каждой серии Test фрейма данных.

Простой печати 'true' или 'false' может быть недостаточно, так как тогда вам придется связать их со своим списком фреймов данных. Вместо этого я рекомендую использовать словарь для хранения фреймов данных:

dict_of_dfs = {fn: pd.read_csv(fn) for fn in filenames}

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

res = {fn: (df['test'] == 0).any() for fn, df in dict_of_dfs.items()}

Затем вы можете определить, что фреймы данных который удовлетворяют вашему условию, выполнив итерацию res.items() или указав конкретное имя файла через res['myfile.csv'].

Обратите внимание, что мы используем векторизованные операции, а не повторяем каждый элемент в серии по одному. Это особенность Pandas, которая отделяет ее от стандартного метода понимания списка Python или выражения генератора, который вы пытались использовать. Векторизованные операции обеспечивают эффективный доступ к непрерывным блокам памяти и должны быть предпочтительнее везде, где это возможно.

Другие вопросы по теме