Как получить строки по максимальной дате, а затем добавить столбец со всеми датами и минимальной датой - PullRequest
0 голосов
/ 06 июня 2018

Я в основном пытаюсь сделать то, что делает этот вопрос: Как получить строки по максимальной дате с определенными столбцами?

Однако я также хочу иметь два новых столбца:

  1. одна вызванная дата (содержащая все даты для данной комбинации I и II, лучше всего, если отсортировано)
  2. одна вызванная min_date (содержащая минимальную дату для данной комбинации I и II).
  3. один названный день (содержащий разницу в днях между максимальными и минимальными датами)

Следуя примеру исходного вопроса:

   I II III        IV        dates                 min_date   days_diff
0  A  X 2017-01-30 some_data 2017-01-30|2017-01-27 2017-01-27 2
1  A  Y 2017-01-30 some_data 2017-01-30|2017-01-27 2017-01-27 2
2  A  Z 2017-01-30 some_data 2017-01-30|2017-01-27 2017-01-27 2
6  B  X 2017-01-30 some_data 2017-01-30|2017-01-27 2017-01-27 2
7  B  Y 2017-01-30 some_data 2017-01-30|2017-01-27 2017-01-27 2
8  B  Z 2017-01-30 some_data 2017-01-30|2017-01-27 2017-01-27 2

Я мог бы сделатьэто в цикле for, находим все строки для каждой уникальной комбинации I и II:

data = [
    ('I', 'II', 'III', 'IV'),
    ('A', 'X', '1/30/2017 9:33:00 AM', 'some_data'),
    ('A', 'Y', '1/30/2017 9:33:00 AM', 'some_data'),
    ('A', 'Z', '1/30/2017 9:33:00 AM', 'some_data'),
    ('A', 'X', '1/27/2017 4:53:00 PM', 'some_data'),
    ('A', 'Y', '1/27/2017 4:53:00 PM', 'some_data'),
    ('A', 'Z', '1/27/2017 4:53:00 PM', 'some_data'),
    ('B', 'X', '1/30/2017 9:33:00 AM', 'some_data'),
    ('B', 'Y', '1/30/2017 9:33:00 AM', 'some_data'),
    ('B', 'Z', '1/30/2017 9:33:00 AM', 'some_data'),
    ('B', 'X', '1/27/2017 4:53:00 PM', 'some_data'),
    ('B', 'Y', '1/27/2017 4:53:00 PM', 'some_data'),
    ('B', 'Z', '1/27/2017 4:53:00 PM', 'some_data'),
]

import pandas as pd
df = pd.DataFrame(data[1:], columns=data[0])
df['III'] = pd.to_datetime(df['III'])

# groupby first two columns, then get the maximum value in the third column
idx = df.groupby(['I', 'II'])['III'].transform(max) == df['III']

# use the index to fetch correct rows in dataframe
df_dedup = df[idx]
df_dedup['dates'] = ''
df_dedup['min_date'] = ''
df_dedup['days_diff'] = ''


# now iterate across all rows of df_dedup and find min and all dates
for idx, row in df_dedup.iterrows():
    target_idx = (df['I'] == row['I']) & (df['II'] == row['II'])
    dates = '|'.join(df[target_idx]['III'].astype('str'))
    min_date = min(df[target_idx]['III'])
    days_diff = row['III']-min_date
    (df_dedup['dates'],df_dedup['min_date'],df_dedup['days_diff']) = dates, min_date, days_diff

Однако, для большого значения df это слишком медленно.Я ищу помощь в векторизации этого с пандами, так что это намного быстрее.любые идеи будут с благодарностью.

Результат для этого конкретного примера будет:

print(df_dedup)
   I II                 III         IV  \
0  A  X 2017-01-30 09:33:00  some_data   
1  A  Y 2017-01-30 09:33:00  some_data   
2  A  Z 2017-01-30 09:33:00  some_data   
6  B  X 2017-01-30 09:33:00  some_data   
7  B  Y 2017-01-30 09:33:00  some_data   
8  B  Z 2017-01-30 09:33:00  some_data   
                                     dates            min_date       days_diff  
0  2017-01-30 09:33:00|2017-01-27 16:53:00 2017-01-27 16:53:00 2 days 16:40:00  
1  2017-01-30 09:33:00|2017-01-27 16:53:00 2017-01-27 16:53:00 2 days 16:40:00  
2  2017-01-30 09:33:00|2017-01-27 16:53:00 2017-01-27 16:53:00 2 days 16:40:00  
6  2017-01-30 09:33:00|2017-01-27 16:53:00 2017-01-27 16:53:00 2 days 16:40:00  
7  2017-01-30 09:33:00|2017-01-27 16:53:00 2017-01-27 16:53:00 2 days 16:40:00  
8  2017-01-30 09:33:00|2017-01-27 16:53:00 2017-01-27 16:53:00 2 days 16:40:00  

1 Ответ

0 голосов
/ 06 июня 2018

Просто следуйте тому, что вы сделали в предыдущем посте, на этот раз нам также нужно подготовить groupby min

s1,s2=df.groupby('I')['III'].transform('min'),df.groupby('I')['III'].transform('max')
df['min_date']=s1;df['dates']=s1.dt.date.astype(str)+'|'+s2.dt.date.astype(str);df['days_diff']=s2-s1
print(df.loc[df['III']==s2,:])
   I II                 III         IV            min_date  \
0  A  X 2017-01-30 09:33:00  some_data 2017-01-27 16:53:00   
1  A  Y 2017-01-30 09:33:00  some_data 2017-01-27 16:53:00   
2  A  Z 2017-01-30 09:33:00  some_data 2017-01-27 16:53:00   
6  B  X 2017-01-30 09:33:00  some_data 2017-01-27 16:53:00   
7  B  Y 2017-01-30 09:33:00  some_data 2017-01-27 16:53:00   
8  B  Z 2017-01-30 09:33:00  some_data 2017-01-27 16:53:00   
                   dates       days_diff  
0  2017-01-27|2017-01-30 2 days 16:40:00  
1  2017-01-27|2017-01-30 2 days 16:40:00  
2  2017-01-27|2017-01-30 2 days 16:40:00  
6  2017-01-27|2017-01-30 2 days 16:40:00  
7  2017-01-27|2017-01-30 2 days 16:40:00  
8  2017-01-27|2017-01-30 2 days 16:40:00  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...