Фильтровать фрейм данных pandas на основе разных dtypes

#python #pandas

#python #pandas

Вопрос:

Я создаю начальный df из файла csv следующим образом:

 knobs_df = pd.read_csv(knobs_container)
        name     type                                             values
0  algorithm   string                                      one;two;three
1    threads  int32_t                1;2;3;4;5;6;7;8;9;10;11;12;13;14;15
 

Для каждой строки я извлекаю в k_values и k_type столбец типа и столбец значений в качестве словарей.

     k_values = {}
    k_types = {}
    for row in knobs_df.itertuples(index=False):
        k_values[row[0]] = row[2].split(';')
        k_types[row[0]] = row[1]

{'algorithm': ['one', 'two', 'three'], 'threads': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15']}
{'algorithm': 'string', 'threads': 'int32_t'}
 

Из k_values словаря я создаю полную сетку, содержащую все возможные комбинации.

    algorithm threads
0        one       1
1        two       1
2      three       1
3        one       2
4        two       2
..       ...     ...
88       two      14
89     three      14
90       one      15
91       two      15
92     three      15
 

Наличие списка ограничений (выражений Python), подобного следующему

 ['threads < 20', 'algorithm != "two"']
 

Я хотел бы отфильтровать фрейм данных с полной сеткой, используя query метод from pandas.DataFrame . Есть ли способ присвоить каждому столбцу соответствующий dtype на основе k_types словаря? Мне нужно это сделать, потому что каждый столбец потенциально имеет независимый тип, и, например, метод запроса не выполняет фильтрацию столбца «потоки», поскольку все столбцы по умолчанию выводятся на «str» во время создания. Проблема в том, что, поскольку изначально типы являются типами данных C , я не знаю, есть ли способ добиться этого.

Возможные k_types:

 [string, short int, int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t, uint32_t, uint64_t, char, int, long int, long long int, int_fast8_t, int_fast16_t, int_fast32_t, int_fast64_t, int_least8_t, int_least_16_t, int_least32_t, int_least64_t, unsigned short int, unsigned char, unsigned int, unsigned long int, unsigned long long int, uint_fast8_t, uint_fast16_t, uint_fast32_t, uint_fast64_t, uint_least8_t, uint_least16_t, uint_least32_t, uint_least64_t, intmax_t, intptr_t, uintmax_t, uintptr_t, float, double, long double]
 

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

1. Вы знаете, что вы можете явно задать dtypes столбца после создания фрейма данных, есть много примеров того, как это сделать на SO.

2. @adirabargil если вы спрашиваете обо всех возможных типах, я могу предоставить список, но в основном это все возможные типы C / C . Я пытаюсь выяснить, можно ли вывести тип из типа C / C . Я знаю, что мы можем принудительно / указать dtype с помощью pandas. Возможно, я неправильно выразился в вопросе, я могу создать новый, если это проблема.

3. Там я предоставил все возможные k_types, которые я могу ожидать.

4. Я подумываю о том, чтобы создать что-то вроде convert_type метода, который с учетом одного из следующих типов возвращает соответствующий тип Python на основе встроенных в стандарт ( docs.python.org/3/library/stdtypes.html ).

5. пожалуйста, ознакомьтесь с ответом и дайте мне знать, подходит ли он

Ответ №1:

мне удалось найти неполное решение из-за некоторого недоразумения. пожалуйста, дайте мне знать, как сделать это решение соответствующим вашим потребностям:

 t_df = df.T
names = t_df.loc['name']
dtypes = t_df.loc['type']
t_df.columns =  names
t_df = t_df.iloc[2:]
dtype_conv = {'string':str,'int32_t':int}
for dtype,name in zip(dtypes,names):
    t_df[name] = t_df[name].str.split(';')
    t_df=t_df.explode(name)
    t_df[name]  =t_df[name].astype(dtype_conv[dtype])
t_df.sort_values('threads').reset_index(drop=True)
 

вывод:

 algorithm   threads
0   one     1
1   two     1
2   three   1
3   one     2
4   two     2
5   three   2
6   one     3
7   two     3
...