PyArrow read_table фильтрует нулевые значения

#parquet #pyarrow

Вопрос:

Я довольно новичок в использовании pyArrow и пытаюсь прочитать файл Parquet, но фильтрую загружаемые данные. У меня есть столбец end_time, и когда я пытаюсь фильтровать по какой-то дате, он работает просто отлично, и я могу фильтровать, чтобы получить только строки, соответствующие моей дате.

 import pyarrow as pa
import pyarrow.parquet as pq
from datetime import datetime
last_updated_at =  datetime(2021,3,5,21,0,23)
table_ad_sets_ongoing = pq.read_table('export/facebook.parquet', filters = [('end_time', '>', last_updated_at)]) 
print(table_ad_sets_ongoing.num_rows)
 

Но у меня также иногда есть нулевое значение в этом поле end_time.
Поэтому я попробовал фильтровать таким образом

 import pyarrow as pa
import pyarrow.parquet as pq
from datetime import datetime
table_ad_sets_ongoing = pq.read_table('export/facebook.parquet', filters = [('end_time', '=', None)]) 
print(table_ad_sets_ongoing.num_rows)
 

Но результат всегда равен 0, даже если у меня действительно есть несколько строк с этим нулевым значением.
После некоторого копания я подозреваю, что это связано с null_selection_behavior, который по умолчанию имеет значение «drop» и поэтому пропускает значения null.https://arrow.apache.org/docs/python/сгенерирован/pyarrow.compute.фильтр.html#pyarrow.вычисление.Фильтр
Я думаю, мне следует добавить этот параметр в «emit_null», но я не могу найти способ сделать это.

Есть идеи?

Спасибо

Ответ №1:

Наконец-то я нашел ответ на свой вопрос. Ответ пришел от arrow github (глупо с моей стороны не взглянуть на него раньше). https://github.com/apache/arrow/issues/9160

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

 import pyarrow as pa
import pyarrow.parquet as pq
import pyarrow.dataset as ds
from datetime import datetime
table_ad_sets_ongoing = pq.read_table('export/facebook.parquet', filters=~ds.field("end_time").is_valid())
print(table_ad_sets_ongoing.num_rows)
 

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

1. Изменить : После обновления до Pyarrow 4.0 кажется, что прямая фильтрация при чтении файла больше невозможна. После некоторого копания нам теперь нужно применить фильтры в 2 раза: сначала загрузите файл в набор данных, а затем примените фильтры. my_dataset = набор данных ds. (‘myparquetFile.parquet’) таблица = my_dataset.to_table(фильтр=~ds.поле(‘данные’).is_valid()) Обратите также внимание, что существует новый фильтр is_null (), который может быть применен вместо is_valid()