可以说我在python中有以下列表。首先按设备排序,然后按日期排序:
my_list = [
{'Equip': 'A-1', 'Job': 'Job 1', 'Date': '2018-01-01'},
{'Equip': 'A-1', 'Job': 'Job 1', 'Date': '2018-01-02'},
{'Equip': 'A-1', 'Job': 'Job 1', 'Date': '2018-01-03'},
{'Equip': 'A-1', 'Job': 'Job 2', 'Date': '2018-01-04'},
{'Equip': 'A-1', 'Job': 'Job 2', 'Date': '2018-01-05'},
{'Equip': 'A-2', 'Job': 'Job 1', 'Date': '2018-01-03'},
{'Equip': 'A-2', 'Job': 'Job 3', 'Date': '2018-01-04'},
{'Equip': 'A-2', 'Job': 'Job 3', 'Date': '2018-01-05'}
]
我要做的是按给定的设备工作不改变的每个集合折叠列表,并获取设备在那里的第一个和最后一个日期。例如,这个简单的示例应更改为:
list_by_job = [
{'Equip': 'A-1', 'Job': 'Job 1', 'First': '2018-01-01', 'Last': '2018-01-03'},
{'Equip': 'A-1', 'Job': 'Job 2', 'First': '2018-01-04', 'Last': '2018-01-05'},
{'Equip': 'A-2', 'Job': 'Job 1', 'First': '2018-01-03', 'Last': '2018-01-03'},
{'Equip': 'A-2', 'Job': 'Job 3', 'First': '2018-01-04', 'Last': '2018-01-05'}
]
需要注意的几件事:
A-2
上的Job 1
仅存在一天,因此其First
和Last
日期应该相同。第3点,列表
my_list = [
{'Equip': 'A-1', 'Job': 'Job 1', 'Date': '2018-01-01'},
{'Equip': 'A-1', 'Job': 'Job 2', 'Date': '2018-01-02'},
{'Equip': 'A-1', 'Job': 'Job 1', 'Date': '2018-01-03'}
]
应该屈服
list_by_job = [
{'Equip': 'A-1', 'Job': 'Job 1', 'First': '2018-01-01', 'Last': '2018-01-01'},
{'Equip': 'A-2', 'Job': 'Job 2', 'First': '2018-01-02', 'Last': '2018-01-02'},
{'Equip': 'A-1', 'Job': 'Job 1', 'First': '2018-01-03', 'Last': '2018-01-03'}
]
目前,我正在以一种简单的循环/非Python方式进行操作:
list_by_job = []
last_entry = None
for entry in my_list:
if last_entry is None or last_entry['Equip'] != entry['Equip'] or last_entry['Job'] != entry['Job']:
list_by_job.append({'Equip': entry['Equip'], 'Job': entry['Job'], 'First': entry['Date'], 'Last': entry['Date']})
else:
list_by_job[-1]['Last'] = entry['Date']
last_entry = entry
使用Python的列表理解等方法是否还有更多的Python方式?
答案 0 :(得分:12)
您可以使用string[] nameArray = new string[] { "Tyler", "Kyle", "Roger", "Rick" };
// Input.
Console.WriteLine(String.Format("Select an item from the array using numbers {0}-{1}", 0, nameArray.Length));
string selectedIndexString = Console.ReadLine();
// Processing.
int selectedIndex = Convert.ToInt32(selectedIndexString);
if (selectedIndex < 0 || selectedIndex >= nameArray.Length)
{
throw new ArgumentException(String.Format("The index must belong to the range: [{0}:{1}]", 0, nameArray.Length));
}
string selectedString = nameArray[selectedIndex];
// Output.
Console.WriteLine(String.Format("You have choosen: {0}", selectedString));
:
itertools.groupby
输出:
import itertools
def _key(d):
return (d['Equip'], d['Job'])
my_list = [{'Date': '2018-01-01', 'Equip': 'A-1', 'Job': 'Job 1'}, {'Date': '2018-01-02', 'Equip': 'A-1', 'Job': 'Job 1'}, {'Date': '2018-01-03', 'Equip': 'A-1', 'Job': 'Job 1'}, {'Date': '2018-01-04', 'Equip': 'A-1', 'Job': 'Job 2'}, {'Date': '2018-01-05', 'Equip': 'A-1', 'Job': 'Job 2'}, {'Date': '2018-01-03', 'Equip': 'A-2', 'Job': 'Job 1'}, {'Date': '2018-01-04', 'Equip': 'A-2', 'Job': 'Job 3'}, {'Date': '2018-01-05', 'Equip': 'A-2', 'Job': 'Job 3'}]
new_data = [[a, list(b)] for a, b in itertools.groupby(my_list, key=_key)]
final_result = [{"Equip":c, 'Job':d, 'First':b[0]['Date'], 'Last':b[-1]['Date']} for [c, d], b in new_data]
编辑:
使用注释中建议的数据:
[{'Equip': 'A-1', 'Job': 'Job 1', 'Last': '2018-01-03', 'First': '2018-01-01'},
{'Equip': 'A-1', 'Job': 'Job 2', 'Last': '2018-01-05', 'First': '2018-01-04'},
{'Equip': 'A-2', 'Job': 'Job 1', 'Last': '2018-01-03', 'First': '2018-01-03'},
{'Equip': 'A-2', 'Job': 'Job 3', 'Last': '2018-01-05', 'First': '2018-01-04'}]
输出:
my_list = [{'Date': '2018-01-01', 'Equip': 'A-1', 'Job': 'Job 1'}, {'Date': '2018-01-02', 'Equip': 'A-1', 'Job': 'Job 2'}, {'Date': '2018-01-03', 'Equip': 'A-1', 'Job': 'Job 1'}, {'Date': '2018-01-04', 'Equip': 'A-1', 'Job': 'Job 2'}, {'Date': '2018-01-05', 'Equip': 'A-1', 'Job': 'Job 2'}, {'Date': '2018-01-03', 'Equip': 'A-2', 'Job': 'Job 1'}, {'Date': '2018-01-04', 'Equip': 'A-2', 'Job': 'Job 3'}, {'Date': '2018-01-05', 'Equip': 'A-2', 'Job': 'Job 3'}]
答案 1 :(得分:3)
我建议为此使用pandas
。
itertools.groupby
很酷,但是IMO却很难理解。
>>> import pandas as pd
>>>
>>> my_list = [
...: {'Equip': 'A-1', 'Job': 'Job 1', 'Date': '2018-01-01'},
...: {'Equip': 'A-1', 'Job': 'Job 1', 'Date': '2018-01-02'},
...: {'Equip': 'A-1', 'Job': 'Job 1', 'Date': '2018-01-03'},
...: {'Equip': 'A-1', 'Job': 'Job 2', 'Date': '2018-01-04'},
...: {'Equip': 'A-1', 'Job': 'Job 2', 'Date': '2018-01-05'},
...: {'Equip': 'A-2', 'Job': 'Job 1', 'Date': '2018-01-03'},
...: {'Equip': 'A-2', 'Job': 'Job 3', 'Date': '2018-01-04'},
...: {'Equip': 'A-2', 'Job': 'Job 3', 'Date': '2018-01-05'}
...:]
>>>
>>> df = pd.DataFrame(my_list)
>>> df['Date'] = pd.to_datetime(df['Date'])
>>> groups = df.groupby(['Equip', 'Job']).agg({'Date': [min, max]}).reset_index()
>>> groups.columns = ['Equip', 'Job', 'First', 'Last']
>>> groups
>>>
Equip Job First Last
0 A-1 Job 1 2018-01-01 2018-01-03
1 A-1 Job 2 2018-01-04 2018-01-05
2 A-2 Job 1 2018-01-03 2018-01-03
3 A-2 Job 3 2018-01-04 2018-01-05
>>>
>>> groups.to_dict(orient='records')
>>>
[{'Equip': 'A-1',
'First': Timestamp('2018-01-01 00:00:00'),
'Job': 'Job 1',
'Last': Timestamp('2018-01-03 00:00:00')},
{'Equip': 'A-1',
'First': Timestamp('2018-01-04 00:00:00'),
'Job': 'Job 2',
'Last': Timestamp('2018-01-05 00:00:00')},
{'Equip': 'A-2',
'First': Timestamp('2018-01-03 00:00:00'),
'Job': 'Job 1',
'Last': Timestamp('2018-01-03 00:00:00')},
{'Equip': 'A-2',
'First': Timestamp('2018-01-04 00:00:00'),
'Job': 'Job 3',
'Last': Timestamp('2018-01-05 00:00:00')}]
我建议保留日期作为时间戳。
答案 2 :(得分:2)
您可以在此处使用pandas,这是某种用于数据的“数据库接口”:
import pandas as pd
df = pd.DataFrame(my_list)
df2 = df.groupby(['Equip', 'Job']).agg(['min', 'max']).rename(columns={'min': 'First', 'max': 'Last'})
df2.columns = df2.columns.droplevel()
df2 = df2.reset_index()
result = df2.to_dict('records')
对于给定的样本输入,得出:
>>> df2.to_dict('records')
[{'Equip': 'A-1', 'Job': 'Job 1', 'First': '2018-01-01', 'Last': '2018-01-03'},
{'Equip': 'A-1', 'Job': 'Job 2', 'First': '2018-01-04', 'Last': '2018-01-05'},
{'Equip': 'A-2', 'Job': 'Job 1', 'First': '2018-01-03', 'Last': '2018-01-03'},
{'Equip': 'A-2', 'Job': 'Job 3', 'First': '2018-01-04', 'Last': '2018-01-05'}]
如果日期格式为 not '%Y-%m-%d'
,则首先需要使用pd.to_datetime(..)
进行转换,例如:
import pandas as pd
df = pd.DataFrame(my_list)
df['Date'] = pd.to_datetime(df['Date'])
df2 = df.groupby(['Equip', 'Job']).agg(['min', 'max']).rename(columns={'min': 'First', 'max': 'Last'})
df2.columns = df2.columns.droplevel()
df2 = df2.reset_index()
result = df2.to_dict('records')