访问熊猫数据框的正确方法[重复]
Posted
技术标签:
【中文标题】访问熊猫数据框的正确方法[重复]【英文标题】:Correct way to access pandas dataframe [duplicate] 【发布时间】:2018-06-29 22:44:25 【问题描述】:我正在尝试从 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)
返回此列标题列表而不是 a ?这是数据框的使用方式吗?有没有更好的方法来访问这些标题/键?
【问题讨论】:
你想在这里做什么?matching
是什么,它应该包含什么?
对于我们这些不知道pvlib
的人来说,cecmod
的类型、结构和典型值是什么?为什么会有一个模块名称列表?作为旁注,数据框df
列名列表在df.columns
中,行名在df.index
中。
cecmod 是一个熊猫数据框。我不确定我能否正确解释数据框,我自己对它们很困惑。它们是对象(熊猫系列)的容器,似乎类似于 2d numpy 数组,其中每一行和每一列都有一个标题。 retrieve_sam() 访问互联网并返回一个数据框,其中包含数千个条目,每个条目都有自己的标题。我想要一个匹配的标题列表。我很困惑,因为从 pvlib 返回的数据帧的行为似乎与熊猫教程中描述的行为不匹配。
cecmod
是一个数据帧。它是一个熊猫数据框;不是pvlib DataFrame
(我不知道这样的东西是否存在)。你可能在某个地方犯了错误。它的行为与其他所有 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')
【讨论】:
matching=df.columns[df.columns.str.find('Trina')!=-1]
可以完全避免 Python 循环。
谢谢。我知道 dir 不是要走的路,但正如我上面所说,pvlib 数据帧的行为似乎不像熊猫教程中描述的数据帧。
稍微编辑了您的答案,如果可以的话。随意回滚。
@GlenS pvlib 从 csv 文件创建 pandas 数据帧。没有“pvlib 数据框”之类的东西。
请注意,由 pvlib 创建的 CEC 模块 DataFrame 会转置原始 csv 文件中的行和列。在我将 DataFrame 转回到行索引中的模块名称和列索引中的参数名称后,搜索模块数据对我来说似乎更容易。cecmod = cecmod.T
以上是关于访问熊猫数据框的正确方法[重复]的主要内容,如果未能解决你的问题,请参考以下文章