У меня есть файлы 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" (поскольку они содержат только нули)
В чем моя ошибка?
i.Test не является типом данных int. проверить по print(i.Test)Еще лучше транслировать тест по серии, а не зацикливаться в выражении генератора: df.i == 0 - это серия логических значений, а (df.i == 0).any() истинно, если любое из этих значений истинно. Или, поскольку 0 неверно, а все остальные числа верны, вы можете использовать not df.i.all(), чтобы получить тот же эффект более эффективно (но, вероятно, менее читабельно).
с кодом минимальный воспроизводимый пример для одного файла с разделителем ',' я не смог воспроизвести проблему. Приведенный выше код возвращает true, если все значения Test являются int, а не float и не str.
@Prateek Я проверил, что list_of_dfs [0] .Test - это тип данных int64. I.Test в этом случае должен быть таким же. Я пытаюсь привести минимальный нерабочий пример. Но было бы слишком много загружать тысячи файлов csv
@RafaelC x == 0 исправил проблему. Большое спасибо
@abarnert (i.Test == 0).any() дал мне те же результаты, что и any(x == 0 for x in i.Test). Однако я могу представить, что ваш метод более эффективен. Могу ли я также вычислить среднее значение DataFrame? Как среднее из тринадцати?
@ChrizZlyBear Да. Под обложками каждая серия (столбец) представляет собой массив numpy, что означает, что вы можете получить все преимущества простоты и производительности от использования numpy на них. (Предполагая, что это числовые столбцы, то есть; если у них есть dtype=object, вы не получите большого преимущества в производительности, а для некоторых сложных типов часто проще использовать функции высокого уровня pandas или даже apply / map, чем раскрывать to numpy.) Таким образом, вы можете получить среднее значение, вызвав на нем sum(), а затем разделив на len, или используя ... Я думаю, что это scipy.stats.mean(i.Thirteen), но вы можете найти его.
Между тем, если вы хотите понять разницу между is и ==, страницу документации и / или соответствующие вопросы SO может быть сложно найти, поэтому дайте мне знать, и я найду ссылку. Но краткий ответ заключается в том, что a is b верен только в том случае, если a и b являются тот же объект, а объект pandas int64 никогда не будет тем же объектом, что и встроенный объект int, в то время как == проверяет, имеют ли они тот же значение, являются ли они один и тот же объект или два разных объекта, которые оказываются равными. Вам почти никогда не понадобится is с числами, но вы часто хотите его со специальными одноэлементными значениями, такими как None.
@abarnert Я только что понял, как много я могу сделать с помощью этого метода. Не только в этом случае. Но это сократило 4 других комплекса петель в один вкладыш. и numpy / SciPy даже не проще. Думаю, они тоже намного эффективнее. Это мне тоже очень помогло.






Постановка проблемы, если я правильно понимаю, состоит в том, чтобы вернуть значение для каждого фрейма данных в списке в зависимости от того, существует ли 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 или выражения генератора, который вы пытались использовать. Векторизованные операции обеспечивают эффективный доступ к непрерывным блокам памяти и должны быть предпочтительнее везде, где это возможно.
Используйте
x==0вместоx is 0