我有一个像这样的defaultdict:
{('Montag', '17.30'): [True, False], ('Dienstag', '16.30'): [True, False], ('Mittwoch', '15.30'): [True, False], ('Donnerstag', '14.30'): [True, False, False, True], ('Freitag', '13.30'): [True, False], ('Samstag', '12.30'): [True, False], ('Sonntag', '11.30'): [True, False], ('Sonntag', '17.30'): [False, True], ('Samstag', '16.30'): [False, True], ('Freitag', '15.30'): [False, True], ('Mittwoch', '13.30'): [False, True], ('Dienstag', '12.30'): [False, True], ('Montag', '11.30'): [False, True], ('Donnerstag', '16.30'): [False, True], ('Samstag', '11.25'): [True,True]})
我想以这样的表格形式打印此内容:
Montag Dienstag Mittwoch Donnerstag Freitag Samstag Sonntag
0 0 0 0 0 100 0 11.25
50 0 0 0 0 0 50 11.30
0 50 0 0 0 50 0 12.30
0 0 50 0 50 0 0 13.30
0 0 0 50 0 0 0 14.30
0 0 50 0 50 0 0 15.30
0 50 0 50 0 50 0 16.30
50 0 0 0 0 0 50 17.30
在x轴上,我想输出dict中彼此相邻的所有日期。 (每天只有一次)
在dict中每次出现的Y轴上都应该相互输出。
该表应使用False和True的比率填充(也许使用statistics.mean())。
我只解决了用以下代码打印轴的问题:
WOCHENTAGE = {0: "Montag",
1: "Dienstag",
2: "Mittwoch",
3: "Donnerstag",
4: "Freitag",
5: "Samstag",
6: "Sonntag"}
set_for_day = set()
set_for_time = set()
for k, v in testdict.items():
set_for_day.add(k[0])
set_for_time.add(k[1])
order = list(WOCHENTAGE.values())
for day in sorted(set_for_day, key = lambda x: order.index(x)):
print(f"{day} ", end ="")
print()
for times in sorted(set_for_time):
print(f" {times}")
答案 0 :(得分:1)
这里的主要挑战是给出数据的格式。 (day,time)
元组作为字典的键,使得很难为字典编制索引以获取每个日期/时间组合的期望值。如下面的代码所示,可以通过将数据转换为可索引为data[day][time]
的字典来返回固定值的百分比来解决此问题。使用您在问题中已经提到的defaultdict
,可以避免为缺失的值填写零。
可以使用sum
计算给定布尔值列表的百分比:每个True
被计为1,每个False
被计为零。除以长度即可得出平均值,再乘以100即可得出百分比。我使用了sum(bool(v) for v in lst)
,以防传入一些非布尔值(例如整数)。如果需要,可以将其更改为sum(lst)
。
以下代码的输出与您所需的输出匹配。
from collections import defaultdict
# The example data.
data = {
('Montag', '17.30'): [True, False],
('Dienstag', '16.30'): [True, False],
('Mittwoch', '15.30'): [True, False],
('Donnerstag', '14.30'): [True, False, False, True],
('Freitag', '13.30'): [True, False],
('Samstag', '12.30'): [True, False],
('Sonntag', '11.30'): [True, False],
('Sonntag', '17.30'): [False, True],
('Samstag', '16.30'): [False, True],
('Freitag', '15.30'): [False, True],
('Mittwoch', '13.30'): [False, True],
('Dienstag', '12.30'): [False, True],
('Montag', '11.30'): [False, True],
('Donnerstag', '16.30'): [False, True],
('Samstag', '11.25'): [True,True]
}
# Week days, in order.
WEEK_DAYS = [
"Montag",
"Dienstag",
"Mittwoch",
"Donnerstag",
"Freitag",
"Samstag",
"Sonntag"
]
# Given a list of values, return the percentage that are truthy.
def percentage_true(lst):
return 100 * sum(bool(v) for v in lst) / len(lst)
# The list of days and times present in the data.
present_days = list(set(k[0] for k in data.keys()))
present_times = list(set(k[1] for k in data.keys()))
# Sort these days based on WEEK_DAYS.
present_days.sort(key = WEEK_DAYS.index)
# Sort the times by converting to minutes.
present_times.sort(key = lambda s: 60 * int(s[:2]) + int(s[3:]))
# Re-organize the data such that it can be indexed as
# data[day][time] => percentage. Use a defaultdict to
# return 0 for absent values.
data = {
day: defaultdict(lambda: 0, {
k[1]: percentage_true(v)
for k, v in data.items() if k[0] == day
})
for day in set(k[0] for k in data.keys())
}
# Print the header.
for day in present_days:
print(day, end=" ")
print()
# For printing, find the lengths of the day names, and the
# formats required for .format().
day_lengths = [len(s) for s in present_days]
perc_formats = ["{{:<{}.0f}}".format(l) for l in day_lengths]
# Print the values row-by-row.
for time in present_times:
for day, fmt in zip(present_days, perc_formats):
print(fmt.format(data[day][time]), end=" ")
print(time)
答案 1 :(得分:0)
尝试一下:
data = {('Montag', '17.30'): [True, False], ('Dienstag', '16.30'): [True, False], ('Mittwoch', '15.30'): [True, False], ('Donnerstag', '14.30'): [True, False, False, True], ('Freitag', '13.30'): [True, False], ('Samstag', '12.30'): [True, False], ('Sonntag', '11.30'): [True, False], ('Sonntag', '17.30'): [False, True], ('Samstag', '16.30'): [False, True], ('Freitag', '15.30'): [False, True], ('Mittwoch', '13.30'): [False, True], ('Dienstag', '12.30'): [False, True], ('Montag', '11.30'): [False, True], ('Donnerstag', '16.30'): [False, True], ('Samstag', '11.25'): [True,True]}
# get unique times
time = []
for item in data:
time.append(item[1])
time_list = list(set(time))
sorted_time = sorted(time_list, key=float)
# set days
days = ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag']
# create data sets
proper_data = []
for time in sorted_time:
for day in days:
for key, value in data.items():
if key[1] == time and key[0] == day:
if value.count(True) == 1:
proper_data.append('50')
elif value.count(True) == 2:
proper_data.append('100')
else:
proper_data.append('0')
proper_data.append(time)
# remove additional items
item_indexes = [n+1 for n,x in enumerate(proper_data) if x=='50' or x =='100']
for index in sorted(item_indexes, reverse=True):
del proper_data[index]
# slice data into parts
final_data = []
for i in range(int(len(proper_data)/8)):
final_data.append(proper_data[(8*i):(8*(i+1))])
# add time to names
days.append('Time')
# print data
final_data = [days] + final_data
for item in final_data:
print("{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}".format(item[0], item[1], item[2], item[3], item[4], item[5], item[6], item[7]))
输出:
Montag Dienstag Mittwoch DonnerstagFreitag Samstag Sonntag Time
0 0 0 0 0 100 0 11.25
50 0 0 0 0 0 50 11.30
0 50 0 0 0 50 0 12.30
0 0 50 0 50 0 0 13.30
0 0 0 100 0 0 0 14.30
0 0 50 0 50 0 0 15.30
0 50 0 50 0 50 0 16.30
50 0 0 0 0 0 50 17.30