#python #dataframe #python-polars
#питон #фрейм данных #питон-поляры
Вопрос:
Я пытаюсь написать небольшой скрипт на python, который считывает .parquet
файл со следующей схемой:
a | b | c | d |
---|---|---|---|
0 | x | 2 | y |
2 | 1 | x | z |
Сценарий принимает следующие аргументы:
- один входной файл
- несколько столбцов
- несколько строк поиска (могут быть строками, числами или регулярным выражением)
Затем он выполняет поиск по заданным столбцам для заданной строки поиска и возвращает всю строку фрейма данных, содержащую заданное значение в данном столбце.
Теперь моя проблема заключается в том, как правильно написать поиск, потому что при текущей реализации я получаю следующую ошибку, если пытаюсь выполнить поиск в столбце с типом dtype, отличным от utf8: RuntimeError: Any(SchemaMisMatch("Series dtype UInt64 != utf8"))
Выполнение программы выглядит следующим образом: pyton ./pqtmgr.py -f './test.parquet' -c 'a' -s '2'
#!/usr/bin/python # Imports import polars import argparse ### MAIN ### # Main def main(): arguments = parse_arguments() dataframe = polars.read_parquet(arguments.files_input) dataframe = dataframe_search(arguments, dataframe) ### MISC ### # Search DataFrame and return a result DataFrame def dataframe_search(arguments, dataframe) -gt; polars.DataFrame: dataframes = [] for column in arguments.columns: for search in arguments.search: dataframes.append( dataframe.filter( (polars.col(column).str.contains(search)) ) ) return polars.concat(dataframes, True, "diagonal") ### ARGUMENTS ### # Parse given arguments def parse_arguments(): parser = argparse.ArgumentParser( prog='pqtmgr.py' ) # Add argument to take an input file parser.add_argument( '-f', '--file-input', dest='fils_input', help=''' Takes one filepath as input file which will be searched ''', required=True ) # Add argument to take a list of columns to search parser.add_argument( '-c', '--columns', dest='columns', help=''' Accepts one or multiple columns that will be searched ''', nargs='*', required=True ) # Add argument to search the given strings parser.add_argument( '-s', '--search', dest='search', help=''' Accepts one or more strings or regular expression that are searched for in the given columns ''', nargs='*' ) # Execute Main if __name__ == '__main__': main()
Комментарии:
1. Ну, типы dtypes могут быть использованы в ваших интересах, верно? Если вы не можете привести строку поиска к плавающему значению, а столбец не имеет типа dtype Utf8, вам даже не нужно искать. Просто нужно написать код проверки типа.
2. Я действительно должен добавить некоторую проверку типов и «попробовать» код… Попытаюсь реализовать это в будущем, но пока ответ jvz делает свое дело, даже если поиск по некоторым столбцам не требуется -gt; неэффективно.
Ответ №1:
Предполагая search
, что это всегда строка, проще всего было бы просто привести к Utf8
, прежде чем переходить в str
пространство имен, если вы хотите выполнить поиск во всех столбцах. Краткий пример:
import polars as pl df = pl.DataFrame({"a": [1, 2, 3], "b": ["hello", "world", "everyone"]}) search = "hello" df["b"].str.contains(search) # this works df["a"].str.contains(search) # this fails, as "a" is not of type Utf8 df["a"].cast(pl.Utf8).str.contains(search) # this works
Комментарии:
1. Теперь это работает как заклинание. Большое спасибо! Совершенно забыл о возможности приведения dtype столбца.