我有一个包含字符串对象,浮动类型和日期的数据集,如下所示:
----------------------------------------------
|str obj col.| Int. Col | Float Col| Date Col|
----------------------------------------------
| str obj. | Int. | Float | Date Obj|
|---------------------------------------------
| str obj. | Int. | Float | Date Obj|
|---------------------------------------------
| str obj. | Int. | Float | Date Obj|
----------------------------------------------
| . | . | . | . |
----------------------------------------------
| . | . | . | . |
----------------------------------------------
| . | . | . | . |
----------------------------------------------
| str obj. | Int. | Float | Date Obj|
----------------------------------------------
日期对象的格式为mm/dd/yyyy。我可以用熊猫把日期按月、按年分组。我通过创建两个列表实现了这一点。一个列表以字符串的形式包含所有年份和月份标签,另一个列表包含数据帧列表。我将它们组合成一个包含dataframe列表的字典。我使用以下命令实现了这一点:
L2 = sorted(set(df['Date'].dt.strftime('%Y-%m').tolist()))
L3 = df.groupby(pd.Grouper(key='Date', freq='M'))
Dict_2 = dict(zip(L2, L3))
然后我创建了一个只包含年份的空字典。因此,我使用了以下代码来生成它:
L1 = sorted(set(df['Date'].dt.strftime('%Y').tolist()))
Dict_1 = dict.fromkeys(L1)
目标是将Dict_1和Dict_2组合成一个按年和月分类的字典。为了达到这个目的,我使用了以下命令:
for year in Dict_1.keys():
for month_year in Dict_2.keys():
if search(str(year), str(month_year)):
Dict_1[year].update({month_year, Dict_2[month_year]})
这样做的基本原理是,如果year字符串匹配month_year字符串,那么将这个新的子键添加到Dict_1。
预期输出为:
Dict_1 = {'2008': {'2008-01': [DataFrame Obj], '2008-02':[DataFrame Obj],...,'2008-12':[DataFrame Obj]}, ..., '2019': {'2019-01': [DataFrame Obj], '2019-02':[DataFrame Obj],...,'2019-12':[DataFrame Obj]}}
然而,我收到以下错误:
AttributeError: 'NoneType' object has no attribute 'update'
我认为这个方法会自发地生成子键并替换包含在这个字典键中的none值,但它根本不这样做。这让我想到了以下三个问题:
首先,我如何将dic_2中的子键添加到dic_1中的空键?其次,如何将dic_2子键中包含的原始信息添加到dic_1键中?最后,除了使用我目前的方法之外,还有更好的方法吗?可能是字典理解或者一些向量化操作?
目标是有一个字典,它有年,月,年,然后是一个DataFrame对象列表。
只寻址for循环
我不能完全复制你正在做的事情。假设在for循环之前的步骤返回正确的输出,这应该可以工作:
for year in L1:
months_dfs_in_year = []
for month_year, df_obj in Dict_2.items():
if search(year, month_year):
months_dfs_in_year.append((month_year, df_obj))
Dict_1[year] = dict(months_dfs_in_year)
注意:一般来说,您应该迭代某些内容并在此过程中对其进行更改。因此,我将Dict_1.keys()
替换为L1
(我会将其命名为更具描述性的东西,如&;years&;)。
for year in Dict_1.keys():
for month_year in Dict_2.keys():
if search(str(year), str(month_year)):
Dict_1[year].update({month_year, Dict_2[month_year]})
Dict_1[year]
:dict[key]
返回与键相关联的值。- 返回
None
,因为Dict_1没有值,只有键。 Dict_1[year] = ...
有效,因为它使值与year键的等号后面紧跟着的值。
- 返回
{month_year, Dict_2[month_year])
是一个集合,不是字典- 字典应该是
{month_year: Dict2[month_year]}
- 字典应该是
dict().update()
更新了key: value对,但是你试图返回一个嵌套在字典中的字典。如果其他一切都工作,除了这个,你已经写了
Dict_1.update({month_year: Dict2[month_year]})
,你会得到一个字典:{'2008': None, '2009': None, ..., '2008-12': [dataframe], ...}
我添加/更改的东西
我在search()中删除了year和month_year周围的str(),它们应该已经是字符串了。似乎没有必要,如果需要的话,把它加回去。
如果没有
months_dfs_in_year
列表,最终结果将只有最后的month_year: [dataframe]
对。每个年键的输出将类似于:
{'2008': {'2008-12': [dataframe]}, '2009': {'2009-12': [dataframe]}, ...}
列表在
for year in L1
之后的循环中,因此它"重置";为L1
中的每个year
。否则,我们最终会得到这样的结果:{'2008': {'2008-01': [dataframe], ..., '2008-12': [dataframe]}, '2009': {'2008-01': [dataframe], ..., '2009-12': [dataframe]}, '2010': {'2008-01': [dataframe], ..., '2010-12': [dataframe]}}
字典理解版本:
而且,主要是因为我先写了这个,但万一你/其他人可能会发现它有用。
使用此方法,您将不需要创建列表或"预创建"。Dict_1 .
Dict_1 = {year: {month_year: df_obj
for month_year, df_obj in Dict_2.items() if search(year, month_year)
}
for year in L1
}