Правильный способ доступа к пандам
Я пытаюсь получить доступ / создать список имен модулей из базы данных CEC, к которой обращается pvlib:
import pandas as pd
import pvlib as pv
cecmod = pv.pvsystem.retrieve_sam('CECMod')
Я хочу найти список имен модулей:
matching = [s for s in dir(cecmod) if "Trina" in s]
dir(cecmod)
часть беспокоит меня Я наткнулся на этот способ получения списка заголовков столбцов данных (ключей?), Но я чувствую, что dir
не предназначен для использования таким образом. Почему dir(pandas.DataFrame)
вернуть этот список заголовков столбцов вместо? Это способ, которым должны использоваться кадры данных? Есть ли лучший способ получить доступ к этим заголовкам / ключам?
1 ответ
Нет, это действительно плохой дизайн. dir(..)
предназначен для перечисления всех атрибутов объекта. Хотя это не всегда возможно, поскольку некоторые объекты генерируют атрибуты на лету.
Это также плохая идея, чтобы проверить с if "Trina" in s
, так как в конечном итоге может случиться, что строка поиска находится в атрибуте.
Способ получить список столбцов просто использовать cecmode.columns
, Который является Index(..)
объект, как:
>>> cecmod.columns
Index(['BEoptCA_Default_Module', 'Example_Module', '1Soltech_1STH_215_P',
'1Soltech_1STH_220_P', '1Soltech_1STH_225_P', '1Soltech_1STH_230_P',
'1Soltech_1STH_235_WH', '1Soltech_1STH_240_WH', '1Soltech_1STH_245_WH',
'1Soltech_1STH_FRL_4H_245_M60_BLK',
...
'Zytech_Solar_ZT275P', 'Zytech_Solar_ZT280P', 'Zytech_Solar_ZT285P',
'Zytech_Solar_ZT290P', 'Zytech_Solar_ZT295P', 'Zytech_Solar_ZT300P',
'Zytech_Solar_ZT305P', 'Zytech_Solar_ZT310P', 'Zytech_Solar_ZT315P',
'Zytech_Solar_ZT320P'],
dtype='object', length=13953)
Он повторяется, а затем мы перебираем имена столбцов:
matching = [col for col in cecmod.columns if "Trina" in col]
который даст:
>>> [col for col in cecmod.columns if "Trina" in col]
['Trina_Solar_TSM_165DA01', 'Trina_Solar_TSM_170D', 'Trina_Solar_TSM_170DA01', 'Trina_Solar_TSM_170DA03', 'Trina_Solar_TSM_170PA03', 'Trina_Solar_TSM_175D', 'Trina_Solar_TSM_175DA01', 'Trina_Solar_TSM_175DA03', 'Trina_Solar_TSM_175PA03', 'Trina_Solar_TSM_180D', 'Trina_Solar_TSM_180DA01', 'Trina_Solar_TSM_180DA03', 'Trina_Solar_TSM_180PA03', 'Trina_Solar_TSM_185DA01', 'Trina_Solar_TSM_185DA01A', 'Trina_Solar_TSM_185DA01A_05', 'Trina_Solar_TSM_185DA01A_08', 'Trina_Solar_TSM_185DA03', 'Trina_Solar_TSM_185PA03', 'Trina_Solar_TSM_190DA01A', 'Trina_Solar_TSM_190DA01A_05', 'Trina_Solar_TSM_190DA01A_08', 'Trina_Solar_TSM_190DA03', 'Trina_Solar_TSM_190PA03', 'Trina_Solar_TSM_195DA01A', 'Trina_Solar_TSM_195DA01A_05', 'Trina_Solar_TSM_195DA01A_08', 'Trina_Solar_TSM_200DA01A', 'Trina_Solar_TSM_200DA01A_05', 'Trina_Solar_TSM_200DA01A_08', 'Trina_Solar_TSM_205DA01A', 'Trina_Solar_TSM_205DA01A_05', 'Trina_Solar_TSM_205DA01A_08', 'Trina_Solar_TSM_220DA05', 'Trina_Solar_TSM_220PA05', 'Trina_Solar_TSM_220PA05_05', ...
(выход отключен).
Мы также можем выполнить более быстрое сопоставление с .str.contains('Trina')
как @DYZ говорит:
list(cecmod.columns[cecmod.columns.str.contains('Trina')])
Здесь мы позволяем библиотеке выполнять работу поиска, которая обычно превосходит циклы Python.
В качестве альтернативы используйте str.startswith
при условии, что строка поиска находится в начале имен столбцов:
list(cecmod.columns[cecmod.columns.str.startswith('Trina')])
Если вам нужны столбцы данных, а не только имена столбцов, используйте df.filter
:
df.filter(like='Trina')