我有一个类似于以下内容的数据框:
| Session | Leg | Talk Time Seconds | ... |
| ------- | --- | ----------------- | --- |
| 1 | 1 | 0 | ... |
| 1 | 2 | 40 | ... |
| 2 | 1 | 35 | ... |
| 2 | 2 | 50 | ... |
| ... | ... | ... | ... |
如果它不是特定会话中的最后一条腿,并且通话时间> 0,则应将该腿标记为已转移,因此:
| Session | Leg | Talk Time Seconds | Transfer | ... |
| ------- | --- | ----------------- | -------- | --- |
| 1 | 1 | 0 | False | ... |
| 1 | 2 | 40 | False | ... |
| 2 | 1 | 35 | True | ... |
| 2 | 2 | 50 | False | ... |
| ... | ... | ... | ... | ... |
我目前正在通过将数据帧分解为每个会话的数据帧列表来完成此操作。使用 apply ,然后将数据帧串联在一起。这需要很长时间才能运行,我想知道是否有更好的方法可以做到这一点。我的代码如下:
# get list of unique sessions
sessions = df['Session'].unique().tolist()
# list of dataframes for each session
session_dfs = [df[df['Session'] == session] for session in sessions]
# if it is not the last leg of the session and talk time is greater than 1 we can assume it is a transfer
for sdf in session_dfs:
last_leg = sdf['Leg'].max()
sdf['Transfer'] = sdf.apply(lambda row: row['Talk Time Seconds'] > 0 if row['Leg'] != last_leg else False, axis=1)
# join all the session dataframes into one dataframe
df = pd.concat(session_dfs)
编辑: 尝试以下建议时:
df['Transfer'] = (
df
.groupby("Session", as_index=True)
.apply(lambda x: (x['Leg'] != x['Leg'].max()) & (x['Talk Time Seconds'].gt(0)))
.reset_index(drop=True)
)
我得到以下输出:
>>> df[(df['Transfer']==1) & (df['Talk Time Seconds'] == 0)][['Session','Leg','Talk Time Seconds','Transfer']]
Session Leg Talk Time Seconds Transfer
11060 51000011288 1 0 True
16167 51000011528 1 0 True
15176 51000012182 1 0 True
8468 51000012228 1 0 True
2175 51000012585 2 0 True
看起来是在通话时间为0的情况下发生的,但这是通话的最后一站:
>>> df[df['Session'] == 51000012585][['Session','Leg','Talk Time Seconds','Transfer']]
Session Leg Talk Time Seconds Transfer
2175 51000012585 2 0 True
3452 51000012585 1 0 False
答案 0 :(得分:2)
这是一种方法。
首先,创建数据框:
d = {'Session': {0: 1, 1: 1, 2: 2, 3: 2},
'Leg': {0: 1, 1: 2, 2: 1, 3: 2},
'TalkTimeSeconds': {0: 0, 1: 40, 2: 35, 3: 50}}
df = pd.DataFrame.from_dict(d)
第二,找到每个会话的最大航段号; .groupby().transform()
返回的序列与原始序列的长度相同。
df['max_leg'] = df.groupby('Session')['Leg'].transform('max')
第三,应用逻辑来识别传输(在最后一站之前,时间> 0):
df['Transfer'] = (df['Leg'] < df['max_leg']) & (df['TalkTimeSeconds'] > 0)
结果显示在下面(我留在max_leg中),以显示groupby / transform语句的结果):
Session Leg TalkTimeSeconds max_leg Transfer
0 1 1 0 2 False
1 1 2 40 2 False
2 2 1 35 2 True
3 2 2 50 2 False
答案 1 :(得分:1)
我建议使用掩码来识别这是否是当前Leg
中的最后一个Session
,以及另一个是否匹配Talk Time Seconds
上的条件。
对于第一部分,您可以group by
获取每个Leg
中最大的Session
,然后使用pd.Series.map
检查条件。对于第二个过去,简单的过滤器就足够了。
以下代码应满足您的要求
df["Transfer"] = (df["Leg"] != df["Session"].map(df.groupby("Session")["Leg"].max())) & (df["Talk Time Seconds"] > 0)
答案 2 :(得分:0)
您可以这样做:
a.index - b.index