python - 如何将函数应用于数据框中一行中的下一个非空单元格
问题描述
我有一个巨大的数据框
23/12/2020 15:38 23/12/2020 15:39 23/12/2020 15:40
1 [12,10] [15,10]
2 [52, 21] [14,7]
3 [1,0] [10,14]
数据框中的值对应于地理坐标。我想要一个新的数据框来说明日期和坐标之间的平均速度。我编写了一个函数distance(wsp1, wsp2)
,它将 2 个坐标列表作为输入并返回它们之间的距离。我还有一个计算两个日期之间差异的函数diff_between_dates(date1, date2)
。我的问题是如何创建一个新的数据框,该数据框将在第一列中具有连续前 2 个非空单元格之间的平均速度,在第二列中具有连续第二个和第三个非空单元格之间的平均速度和很快。因此,在我的示例中,所需的输出将是:
1
1 distance([15,10],[12,10])/diff_between_dates(23/12/2020 15:40,23/12/2020 15:39)
2 distance([52,21],[14,7])/diff_between_dates(23/12/2020 15:40,23/12/2020 15:38)
3 distance([10,14],[1,0])/diff_between_dates(23/12/2020 15:39,23/12/2020 15:38)
解决方案
import io
import pandas as pd
import numpy as np
# create sample df
df_str = '''
23/12/2020 15:38;23/12/2020 15:39;23/12/2020 15:40
;[12,10];[15,10]
[52, 21];;[14,7]
[1,0];[10,14];
'''
df = pd.read_csv(io.StringIO(df_str.strip()), sep=';')
df.index = [1,2,3]
df = df.applymap(lambda x: eval(x) if isinstance(x, str) else x)
print(df)
# 23/12/2020 15:38 23/12/2020 15:39 23/12/2020 15:40
# 1 NaN [12, 10] [15, 10]
# 2 [52, 21] NaN [14, 7]
# 3 [1, 0] [10, 14] NaN
# stack -> DataFrame to Series -> reset_index
dfn = df.stack().reset_index()
dfn.columns = ['idx', 'time', 'coor']
print(dfn)
# idx time coor
# 0 1 23/12/2020 15:39 [12, 10]
# 1 1 23/12/2020 15:40 [15, 10]
# 2 2 23/12/2020 15:38 [52, 21]
# 3 2 23/12/2020 15:40 [14, 7]
# 4 3 23/12/2020 15:38 [1, 0]
# 5 3 23/12/2020 15:39 [10, 14]
# convert datatime
dfn['time'] = pd.to_datetime(dfn['time'])
print(dfn)
# idx time coor
# 0 1 2020-12-23 15:39:00 [12, 10]
# 1 1 2020-12-23 15:40:00 [15, 10]
# 2 2 2020-12-23 15:38:00 [52, 21]
# 3 2 2020-12-23 15:40:00 [14, 7]
# 4 3 2020-12-23 15:38:00 [1, 0]
# 5 3 2020-12-23 15:39:00 [10, 14]
# sort values by idx and time
dfn.sort_values(['idx', 'time'], inplace=True)
# def sample function
def distance(x,y):
res = abs(x[0] - x[1]) ** 2 + abs(y[0] - y[1]) ** 2
res = np.sqrt(res)
return res
def diff_between_dates(x,y):
time_diff = abs(pd.to_datetime(x) - pd.to_datetime(y))
return time_diff.seconds
# calculate by split dfn by group using idx
res_dict = dict()
for idx, group in dfn.groupby('idx'):
# can modify by purpose
dates = group.iloc[:2, 1].tolist()
coors = group.iloc[:2, 2].tolist()
# calculate use function
dist_diff = distance(*coors)
dates_diff = diff_between_dates(*dates)
result = dist_diff/dates_diff
res_dict[idx] = result
obj_res = pd.Series(res_dict)
print(obj_res)
# 1 0.089753
# 2 0.264837
# 3 0.068718
# dtype: float64
推荐阅读
- angularjs - 如何从 angularjs 中的表单读取用户输入并创建 yaml?
- c# - 如何在 C# 中读取和写入文本文件的第一行?
- cuda - 我可以使用什么代替 LOP3 指令来处理 uint64_t 数据类型并使用一条指令执行 3 个操作数逻辑运算?
- java - Firebase 问题 java.lang.NoSuchMethodError: No virtual method zzbqp()Ljava/lang/String; 在 Lcom/google/firebase/FirebaseApp 类中;
- python - Tkinter 画布未在无限循环中更新
- php - Laravel 5.4 供应商发布组件不起作用
- angularjs - 在angularjs中关闭浏览器/选项卡时删除本地存储数据
- mysql - 无法使用 pymysql 从我的 sql 数据库中检索数据
- html - 我将如何使用 Google Apps 脚本显示用户输入 URL 的 HTML?
- php - 如何使用 ActiveDataprovider 在 Yii2 GridView 中显示数组数据