python - Pandas:基于现有行的新行
问题描述
df
我有一个具有以下结构的 Pandas 数据框:dataId, nodeId, tickDatetime
该数据集表示时间 ( tickDatetime
),其中元素 ( dataId
) 通过节点 ( nodeId
)。
这是一个例子:
dataId nodeId tickDatetime
0 data-0 node-01 3000
1 data-0 node-02 5000
2 data-1 node-02 4000
3 data-1 node-01 6000
4 data-0 node-01 8000
5 data-0 node-00 10000
... ... ...
从这个数据框中,我想创建一个新的数据框routes
,其中包含节点序列和每个dataId
.
所以我做了以下事情:
routes = df.sort_values('tickDatetime').groupby('dataId').agg({'nodeId':[lambda x: list(x)],'tickDatetime':lambda x: list(x)})
def datetimes_to_travel_times(datetimes):
traveltimes = np.empty(len(datetimes))
old_value = datetimes[0]
traveltimes[0] = 0
for i in range(1,len(datetimes)):
traveltimes[i] = datetimes[i] - old_value
old_value = datetimes[i]
return traveltimes
routes['traveltimes'] = routes['tickDatetime'].apply(lambda row: datetimes_to_travel_times(row))
这给了我预期的输出(也许不是最好的方法?):
dataId nodeId tickDatetime traveltimes
0 data-0 [node-01,node-02,node-01,node-00] [3000,5000,8000,10000] [0,2000,3000,2000]
1 data-1 [node-02,node-01] [4000,6000] [0,2000]
现在,如果旅行时间超过某个阈值,我希望我的路线被拆分。
例如,阈值为 3000,我希望我的routes
数据框看起来像这样:
dataId routeId nodeId tickDatetime traveltimes
0 data-0 0 [node-01,node-02] [3000,5000] [0,2000]
1 data-0 1 [node-01,node-00] [8000,10000] [0,2000]
2 data-1 0 [node-02,node-01] [4000,6000] [0,2000]
如何使用 Pandas 实现这一目标?
编辑 :
我设法解决了我的问题:
def split_routes(row):
threshold = 3000
nodes = row['nodeId']
traveltimes = row['traveltimes']
rows = []
route_id = 0
route_nodes = []
route_traveltimes = []
for i in range(0, len(traveltimes)):
if(traveltimes[i]<threshold):
route_nodes.append(nodes[i])
route_traveltimes.append(traveltimes[i])
else :
# Route route_id completed, starting a new one
row['route_id'] = route_id
row['Reader'] = route_nodes
row['traveltimes'] = route_traveltimes
rows.append(row)
route_id+=1
route_nodes.append(nodes[i])
route_traveltimes.append(0)
# Route route_id completed, starting a new one
row['route_id'] = route_id
row['Reader'] = route_nodes
row['traveltimes'] = route_traveltimes
rows.append(row)
return pd.DataFrame(rows)
splitted_routes_array = []
for index, row in routes.iterrows():
splitted_routes_array.append(split_routes(row))
splitted_routes = pd.concat(splitted_routes_array)
解决方案
df = pd.DataFrame({
'dataId':['data-0','data-0','data-1','data-1','data-0','data-0'],
'nodeId':['node-01','node-02','node-02','node-01','node-01','node-00'],
'tickDatetime':[3000,5000,4000,6000,8000,10000]})
append_ = lambda x:list(x)
df_2 = pd.DataFrame()
df_2['nodeId'] = df.groupby('dataId')['nodeId'].apply(append_)
df_2['tickDatetime'] = df.groupby('dataId')['tickDatetime'].apply(append_)
print(df_2)
输出:
nodeId tickDatetime
dataId
data-0 [node-01, node-02, node-01, node-00] [3000, 5000, 8000, 10000]
data-1 [node-02, node-01] [4000, 6000]
推荐阅读
- ios - iOS13删除应用后自动记住应用权限
- windows-services - Windows 服务不会在 Windows 7 上自动启动
- r - R Markdown,循环输出测试结果
- devops - Jelastic - 使用 PM2 进行零停机部署
- api - 如果 graphql 是一种查询语言,为什么它用在前端而不是后端?
- apify - PuppeteerCrawler 和 Task 的 Settigs 差异
- oracle - PLS-00103:结束而不是编译指示最终实例化顺序覆盖静态成员构造函数映射
- java - JSP 代码超出了 65535 字节的限制 - Tomcat 9 修复
- android - 只要应用程序打开,如何使用socket.io保持活跃的android webview
- java - 哪些声明是有效的?