I a*_*Nik 8 python loops pandas
假设我有一个包含两列的pandas数据帧:ID和Days.DataFrame在两个变量中按升序排序.例如:
# Initial dataset
data = pd.DataFrame({'id': np.repeat([1, 2 ,3], 4),
'day': [1, 2, 10, 11, 3, 4, 12, 15, 1, 20, 21, 24]})
id day
0 1 1
1 1 2
2 1 10
3 1 11
4 2 3
5 2 4
6 2 12
7 2 15
8 3 1
9 3 20
10 3 21
11 3 24
Run Code Online (Sandbox Code Playgroud)
我想添加第三列,它会为每个ID*日提供一个"会话"号."会话"是指在一个会话期间之间差异小于2天的一系列天数.例如,序列5,6,7将被视为一个会话,而5,6,9将被视为两个会话,并且应该被标记为0, 0, 1,即第5天和第6天被引用到会话#0,而第9天被引用到会话#1.会话编号应该从0每个新ID开始.
换句话说,我想得到的是:
id day session
0 1 1 0
1 1 2 0
2 1 10 1
3 1 11 1
4 2 3 0
5 2 4 0
6 2 12 1
7 2 15 2
8 3 1 0
9 3 20 1
10 3 21 1
11 3 24 2
Run Code Online (Sandbox Code Playgroud)
为了解决这个问题,我使用了基本的for循环.在此循环中,我迭代地遍历所有唯一ID,然后从初始数据集中对数据块进行子集化,并为特定ID的每一天分配会话编号.我有这个问题 - 因为初始数据集是数百万行 - 循环需要时间!例如,对于1毫升的线,我的循环花费大约一分钟,这太多了.
如何提高速度?任何方法都很好!如果你知道如何达到预期的结果,例如,一些numpy矩阵操作会减少时间 - 也很好......
我的循环代码:
# Get sessions for every id
sessions = []
for i in data.id.unique():
id_data = data['day'][data['id']==i].reset_index(drop=True)
for ind in id_data.index:
if ind == 0:
temp = [0]
elif ((id_data[ind] - id_data[ind - 1]) < 2):
temp.append(temp[ind - 1])
else:
temp.append(temp[ind - 1] + 1)
sessions.extend(temp)
# Add sessions to the table
data['session'] = sessions
Run Code Online (Sandbox Code Playgroud)
你可以加上布尔值
data.groupby('id').day.apply(lambda x : x.diff().gt(1).cumsum())
Out[614]:
0 0
1 0
2 1
3 1
4 0
5 0
6 1
7 2
8 0
9 1
10 1
11 2
Name: day, dtype: int32
Run Code Online (Sandbox Code Playgroud)
我们可以利用这样一个事实,即您的数据经过排序以消除fillna,减少两次groupby调用,并消除对数据的需求apply.
df['session'] = df.day.diff().ge(2)
df['session'] = df.groupby('id').session.cumsum()
Run Code Online (Sandbox Code Playgroud)
df
id day session
0 1 1 0.0
1 1 2 0.0
2 1 10 1.0
3 1 11 1.0
4 2 3 0.0
5 2 4 0.0
6 2 12 1.0
7 2 15 2.0
8 3 1 0.0
9 3 20 1.0
10 3 21 1.0
11 3 24 2.0
Run Code Online (Sandbox Code Playgroud)
作为回报,"session"将是一个浮动列.
您可以使用,和groupby()两次:np.where()diff()cumsum()
data['session'] = np.where(data.groupby('id')['day'].diff().fillna(0)>1, 1, 0)
data['session'] = data.groupby('id')['session'].cumsum()
Run Code Online (Sandbox Code Playgroud)
产量:
id day session
0 1 1 0
1 1 2 0
2 1 10 1
3 1 11 1
4 2 3 0
5 2 4 0
6 2 12 1
7 2 15 2
8 3 1 0
9 3 20 1
10 3 21 1
11 3 24 2
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
284 次 |
| 最近记录: |