假设有一个狂人日记的 dataframe 如下:
user_name |
publish_time |
content |
小明 |
2022-12-30 15:10:00 |
今天是 2022 年最后一天,我在广东 |
小刚 |
2022-01-01 12:23:33 |
今天是 2022 年第一天,我在加勒比 |
小王 |
2022-01-01 12:33:00 |
今天是 2022 年第一天,我在小刚身边 |
小刚 |
2023-01-01 02:15:45 |
今天是 2023 年第一天,我在百慕大 |
小明 |
2023-01-01 00:05:20 |
今天是 2023 年第一天,我还在广东 |
现在我们要统计狂人日记里面,同一作者第一次和最后一次发布时间差大于 30 天的行。
乍一看,首先必须统计同一作者至少发布两次的行,也就是上一篇value counts 的内容。
然后再使用 groupby 分组 + filter 过滤实现,这个 filter 相当于 mysql 语句中 groupby 后的 having 语句,是在分组上做筛选的。
所以在上一篇的基础上,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
import pandas as pd
input_file = './狂人日记 2022.csv'
def remove_show_count_below_n(input_file, col, n=2): df = pd.read_csv(input_file) count_df = pd.DataFrame(df[col].value_counts()) count_df.columns = ['count'] not_below_n_index = count_df[count_df['count'] >= n].index df = df[df[col].isin(not_below_n_index)]
df['publish_date'] = pd.to_datetime(df['publish_time']).dt.date df = df.groupby(col).filter(lambda x: (x['publish_date'].max() - x['publish_date'].min()).days > 30)
df.to_csv('result.csv', index=False, encoding='utf-8-sig')
remove_show_count_below_n(input_file, col='user_name')
|
仔细想想,第一步真的有必要吗?如果只出现一次,在第二步 publish_date 相减的时候差值为 0,直接就过滤掉了,所以第一步在这个任务是多此一举。简化代码如下:
1 2 3 4 5 6 7
| def time_interval_filter(input_file, col, days): df = pd.read_csv(input_file) df['publish_date'] = pd.to_datetime(df['publish_time']).dt.date df = df.groupby(col).filter(lambda x: (x['publish_date'].max() - x['publish_date'].min()).days > days) df.to_csv('result.csv', index=False, encoding='utf-8-sig')
time_interval_filter(input_file, col='user_name', days=30)
|