访问 pandas 数据框的正确方法
Correct way to access pandas dataframe
我正在尝试 access/create 来自 pvlib 访问的 CEC 数据库的模块名称列表:
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)
return 这个列标题列表而不是 a ?这是数据帧的使用方式吗?有没有更好的方法来访问这些 headings/keys?
不,这真是糟糕的设计。 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', ...
(输出被切断)
我们还可以像@DYZ 说的那样用 .str.contains('Trina')
执行更快的匹配:
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')
我正在尝试 access/create 来自 pvlib 访问的 CEC 数据库的模块名称列表:
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)
return 这个列标题列表而不是 a ?这是数据帧的使用方式吗?有没有更好的方法来访问这些 headings/keys?
不,这真是糟糕的设计。 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', ...
(输出被切断)
我们还可以像@DYZ 说的那样用 .str.contains('Trina')
执行更快的匹配:
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')