python-3.x - 我可以在这里应用矢量化吗?还是我应该换个角度思考这个问题?
问题描述
简而言之,我在一年中的某个特定月份发生了多行活动。我想在此活动之间添加额外的不活动行,同时将月份值重置为序列。例如,如果我有 2、5、7 个月,我需要将它们映射到 1、4、7,而我的非活动月份发生在 2、3、5 和 6。所以,我必须添加四行这种不活动。我已经使用字典和 for 循环完成了这项工作,但我知道这效率不高,尤其是当我将其移动到数千行数据进行处理时。关于如何优化它的任何建议?我是否需要以不同的方式考虑数据格式?我曾建议制作列表,然后将其移至最后的数据框,但我认为那里并没有很大的收获。我对 NumPy 的了解还不够,无法弄清楚如何通过矢量化来做到这一点,因为那 s 超级快,学习新东西会很棒。以下是我采取的步骤的代码:
df = pd.DataFrame({'col1': ['A','A', 'B','B','B','C','C'], 'col2': ['X','Y','X','Y','Z','Y','Y'], 'col3': [1, 8, 2, 5, 7, 6, 7]})
输出:
col1 col2 col3
0 A X 1
1 A Y 8
2 B X 2
3 B Y 5
4 B Z 7
5 C Y 6
6 C Y 7
我正在创建一个字典来处理这个 for 循环:
df1 = df.groupby('col1')['col3'].apply(list).to_dict()
df2 = df.groupby('col1')['col2'].apply(list).to_dict()
max_num = max(df.col3)
输出:
{'A': [1, 8], 'B': [2, 5, 7], 'C': [6, 7]}
{'A': ['X', 'Y'], 'B': ['X', 'Y', 'Z'], 'C': ['Y', 'Y']}
8
现在我通过创建一个新的数据框使用我的字典添加这些行:
df_new = pd.DataFrame({'col1': [], 'col2': [], 'col3': []})
for key in df1.keys():
k = 1
if list(df1[key])[-1] - list(df1[key])[0] + 1 < max_num:
for i in list(range(list(df1[key])[0], list(df1[key])[-1] + 1, 1)):
if i in df1[key]:
df_new = df_new.append({'col1': key, 'col2': list(df2[key])[list(df1[key]).index(i)],'col3': str(k)}, ignore_index=True)
else:
df_new = df_new.append({'col1': key, 'col2': 'N' ,'col3': str(k)}, ignore_index=True)
k += 1
df_new = df_new.append({'col1': key, 'col2': 'E', 'col3': str(k)}, ignore_index=True)
else:
for i in list(range(list(df1[key])[0], list(df1[key])[-1] + 1, 1)):
if i in df1[key]:
df_new = df_new.append({'col1': key, 'col2': list(df2[key])[list(df1[key]).index(i)],'col3': str(k)}, ignore_index=True)
else:
df_new = df_new.append({'col1': key, 'col2': 'N' ,'col3': str(k)}, ignore_index=True)
k += 1
输出:
col1 col2 col3
0 A X 1
1 A N 2
2 A N 3
3 A N 4
4 A N 5
5 A N 6
6 A N 7
7 A Y 8
8 B X 1
9 B N 2
10 B N 3
11 B Y 4
12 B N 5
13 B Z 6
14 B E 7
15 C Y 1
16 C Y 2
17 C E 3
然后我转向我想要的形式:
df_pivot = df_new.pivot(index='col1', columns='col3', values='col2')
输出:
col3 1 2 3 4 5 6 7 8
col1
A X N N N N N N Y
B X N N Y N Z E NaN
C Y Y E NaN NaN NaN NaN NaN
谢谢您的帮助。
解决方案
我们可以用下面的语句替换创建和使用字典的步骤,该语句reindex
用于放置附加值N
并且E
没有显式循环。
df_new = df.set_index('col3')\
.groupby('col1')\
.apply(lambda dg:
dg.drop('col1', 1)
.reindex(range(dg.index.min(), dg.index.max()+1), fill_value='N')
.reindex(range(dg.index.min(), min(max_num, dg.index.max()+1)+1), fill_value='E')
.set_index(pd.RangeIndex(1, min(max_num, dg.index.max()-dg.index.min()+1+1)+1, name='col3'))
)\
.reset_index()
在此之后,您可以pivot
按原样应用您的声明。
推荐阅读
- java - 如何避免 Spring Boot API 中出现 NumberFormatException
- javascript - 有没有办法从 JavaScript 的 setTimeout 循环中退出 if 语句?
- python - 尝试下载 MNIST 数据时出现 HTTP 错误
- python - 将句子中的 N 位数字替换为 N 的不同值的特定字符串
- python - 为什么函数不检查到最后一个数字?
- javascript - 对带有异常的 javascript 对象进行排序
- python - 在数值对数 X 轴上绘制垂直箱线图
- .net-core - 相同的功能有时会让我退出 (ReturnUrl)
- sql - 仅显示结果 > 2
- c - 如何使用两个指针来定义一个字符串isPalindrome?