簡體   English   中英

Python-如何從sqlite3列創建嵌套字典並使用Matplotlib對其進行圖形繪制?

[英]Python - How to create a nested dictionary from sqlite3 columns and graph it using Matplotlib?

我正在嘗試從我根據看過的動畫(長數百個條目)創建的數據庫的sqlite3列中創建嵌套字典。 數據庫中的兩列是“ DateWatched”,這是我觀看該特定動漫的日期(例如6月6日至6月8日,等等),另一列是“年”,這是我觀看該動漫的年份。

這是兩列中數據的一個小示例:

      DateWatched                | Year
---------------------------------+----------------
Dec 18-Dec 23                    | 2013
Dec 25-Jan 10                    | 2013 and 2014
Feb 2014 and Jan 1-Jan 3 2016    | 2014 and 2016   #Some anime get another season years later so any date after an "and" is another season
Mar 10th                         | 2014
Mar 13th                         | 2014

這是我的兩篇專欄文章的基本結構。 我想要做的是將其存儲在字典或列表中,並跟蹤我每年(從一月到十二月)每年看多少動畫。

我想我希望它像這樣(基於我的示例):

Final = {'2013':{'Dec':2},
         '2014':{'Jan':1, 'Feb':1,'Mar':2}
         '2016':{'Jan':1}}

我想出了如何分別創建每個列的列表:

MonthColumn = [i[0] for i in c.execute("SELECT DateWatched FROM Anime").fetchall()]  #'Anime' is just the name of arbitrary name for the database
x = [item.replace('-',' ') for item in [y for x in MonthColumn for y in re.split(' and ', x)]]  #Gets rid of '-' in each row and splits into two strings any place with an 'and'
v = [' '.join(OrderedDict((w,w) for w in item.split()).keys()) for item in x]  # Removes duplicate words ("Dec 18-Dec 23" becomes "Dec 18 23")
j = [y for j in v for y in j.split()]  #Splits into separate strings ("Dec 18 23" becomes "Dec", "18", "23")
Month = [item for item in j if item.isalpha()] #Final list and removes any string with numbers (So "Dec","18","23" becomes "Dec")

YearColumn = [i[0] for i in c.execute("SELECT Year FROM Anime").fetchall()]
Year = [item for Year in YearColumn for item in re.split(' and ', Year)]  #Final list and removes any "and" and splits the string into 2 (So "2013 and 2014" becomes "2013","2014")

#So in the example columns I gave above, my final lists become
Month = ['Dec','Dec','Jan','Feb','Jan','Mar','Mar']
Year =  ['2013','2013','2014','2014','2016','2014',2014']

最大的問題和我需要最大幫助的地方是試圖弄清楚如何將兩個列表轉換為嵌套字典或類似的東西,並在Matplotlib中使用它來創建以年份為x軸的條形圖(其中12條為每年),y軸是x軸上每年該月觀看的動漫數量。

感謝您的幫助,如果我錯過了任何內容或未提供任何內容(第一次發帖),我們深表歉意。

我建議使用稍有不同的解析方法來處理月度范圍,需要將其考慮在內以實現所需的可視化字典,然后可以用來創建更清晰的圖:

import re, sqlite3 
import itertools, collections
data = list(sqlite3.connect('db_tablename.db').cursor().execute("SELECT  DateWatched, Year FROM tablename"))
new_parsed = [[list(filter(lambda x:x != 'and', re.findall('[a-zA-Z]+', a))), re.findall('\d+', b)] for a, b in data]
new_results = [i for b in [list(zip(*i)) for i in new_parsed] for i in b]
groups = {a:collections.Counter([c for c, _ in b]) for a, b in itertools.groupby(sorted(new_results, key=lambda x:x[-1]), key=lambda x:x[-1])}

結果為{'2013': Counter({'Dec': 2}), '2014': Counter({'Mar': 2, 'Jan': 1, 'Feb': 1}), '2016': Counter({'Jan': 1})}

繪制:

import matplotlib.pyplot as plt
months = ['Dec', 'Jan', 'Feb', 'Mar']
new_months = {a:[[i, b.get(i, 0)] for i in months] for a, b in groups.items()}
labels = iter(['Dec', 'Jan', 'Feb', 'Mar'][::-1])
for i in range(len(new_months['2013'])):
  i = len(new_months['2013'])-i-1
  _current = [b[i][-1] for _, b in sorted(new_months.items(), key=lambda x:int(x[0]))]
  _previous = [sum(c[-1] for c in b[:-i]) for _, b in sorted(new_months.items(), key=lambda x:int(x[0]))]
  if not all(_previous):
     plt.bar(range(len(new_months)), _current, label = next(labels))
  else:
     plt.bar(range(len(new_months)), _current, label = next(labels), bottom = _previous)

plt.xticks(range(len(new_months)), sorted(new_months, key=lambda x:int(x)))
plt.legend(loc='upper left')
plt.show()

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM