python - 从组矩阵中找到时间序列顺序的最佳方法
问题描述
有这样做的标准方法吗?
我基本上有一些用户,他们一起执行操作并作为一个组分开。我们不知道事件的顺序,但可以推断它们:
A B C D E
WentToMall 1 1 1 0 0
DroveToTheMovies 1 0 0 0 0
AteLunchTogether 1 1 0 0 0
BoughtClothes 1 1 0 0 1
BoughtElectronics 1 1 0 0 0
规则是它们之后不能聚合在一起。所以时间序列看起来像:
时间 0 总是将它们全部放在一起,然后最大的“分组”分裂为“WentToMall”,我们将 A、B、C 和 D、E 分开。
从那里开始,看起来 AB 与 C 分离,AB 继续进行“AteLunchTogether, BoughtClothes, BoughtElectronics”。在“买衣服”期间的某个时候,看起来 E 与 D 分开了。最后,A 和 B 在最后分开,因为 A '开车去看电影'。
如果可能的话,我还想直观地显示这一点,也许节点显示分隔拆分的事件数(看起来像):
ABCDE ---> ABC --> AB ->A
| | |->B
| |
| |--> C
|
|
|---> DE --> D
|-->E
出现的一个问题是有时您会得到“难以评估”或看起来矛盾的时间点,并且不适合基于最少数量的列。我也不知道该怎么处理这些。我被赋予了动作的“权重”,所以我可以据此做出决定,或者我猜想生成图表的所有版本。
我在想也许是递归进行搜索,或者类似的?
解决方案
编辑:最新文件在这里
该过程是通过递归。Pandas 在您的场景中很有用,尽管可能有更有效的方法可以做到这一点。
我们从进一步的节点中搜索。在您的情况下,这些将是 A 和 E 节点。我们怎么知道这些是最远的节点?只需计算所有行的 0 和 1 值。然后得到 0 和 1 值的总和。此外,按 0 对值进行排序。对于第一种情况,它应该是这样的:
0 1
DroveToTheMovies 4.0 1.0
AteLunchTogether 3.0 2.0
BoughtElectronics 3.0 2.0
WentToMall 2.0 3.0
BoughtClothes 2.0 3.0
FirstCase 0.0 5.0
这意味着有 1 人开车去看电影。你看到了模式。后来有人加入这个人。在第一种情况下,我们开始时有 5 个人。但有一个问题。我们如何知道前一个人是否在组中?假设 X 开车去看电影。现在我们检查吃午饭。假设 Y 和 Z 加入了该组,但不是 X。对于这种情况,我们将检查最新的组是否在新组中。因此,在我们到达第一种情况之前,我们将所有事件添加到一个数组中。所以现在我们有一个分支。
假设有人不在群体案例中。在这种情况下,我们也存储了这种奇怪的行为。那么,我们现在就从那里出发。在第一种情况下,我们的起始节点是 A;不是 B 使用相同的技术。所以这个过程将再次重复。
我的最终结果是这样的:
0 1
0 DroveToTheMovies Index(['A'], dtype='object')
1 AteLunchTogether Index(['A', 'B'], dtype='object')
2 BoughtElectronics Index(['A', 'B'], dtype='object')
3 WentToMall Index(['A', 'B', 'C'], dtype='object')
4 FirstCase Index(['A', 'B', 'C', 'D', 'E'], dtype='object')
5 BoughtClothes Index(['E'], dtype='object')
6 FirstCase Index(['D', 'E'], dtype='object')
有两个 FirstCase。但是你需要处理这两个 FirstCase 值并知道,这个 DE 组来自第一个 FirstCase 组,然后 E 去买衣服。D 是未知的,因此可以分配为其他东西。你有它。
第一个分支:
ABCDE ---> ABC --> AB ->A
| |->B
|
|--> C
第二支:
(first case)---> DE --> D
|-->E
你现在要做的就是找到谁离开了分支。对于第一个分支,它是 B、C 和 DE。从现在开始,这些很容易计算。希望它会帮助你。代码在这里,我建议调试代码以使整个想法更清晰:
import pandas as pd
df = pd.DataFrame(
[[1, 1, 1, 0, 0],
[1, 0, 0, 0, 0],
[1, 1, 0, 0, 0],
[1, 1, 0, 0, 1],
[1, 1, 0, 0, 0]], columns=list("ABCDE"))
df.index = ['WentToMall', 'DroveToTheMovies', 'AteLunchTogether', 'BoughtClothes', 'BoughtElectronics']
first_case = pd.DataFrame(
[[1, 1, 1, 1, 1]], columns=list("ABCDE"), index=['FirstCase'])
all_case = pd.concat([first_case, df])
def case_finder(all_case):
df_case = all_case.apply(lambda x: x.value_counts(), axis=1).fillna(0)
df_case = df_case.loc[df_case[1] != 0]
return df_case.sort_values(by=1)
def check_together(x):
x = df.iloc[x]
activity = all_case.loc[x.name]
does_activity = activity.loc[activity == 1]
return activity.name, does_activity.index
def check_in(pre, now):
return pre.isin(now).all()
def check_odd(i):
act = check_together(i)[0]
who = check_together(i)[1][~check_together(i)[1].isin(check_together(i-1)[1])]
return act, who
df = case_finder(all_case)
total = all_case.shape[0]
all_acts = []
last_stable = []
while True:
for i in range(total):
act, ind = check_together(i)
if ind.size == 1:
print("Initiliazed!")
all_acts.append([act, ind])
pass
else:
p_act, p_ind = check_together(i-1)
if check_in(p_ind, ind) == True:
print("So a new person joins us!")
all_acts.append([act, ind])
else:
print("This is weird. We'll check later!")
# act, who = check_odd(i)
last_stable.append([i, p_ind])
continue
if act == 'FirstCase':
break
if len(last_stable) == 0:
print("Process done!")
break
else:
print("Update cases!")
ls_ind = last_stable[0]
all_case = all_case.drop(last_stable[0][1], axis=1)
total = all_case.shape[0]
df = case_finder(all_case)
last_stable = last_stable[1:]
print(all_acts)
x = pd.DataFrame(all_acts)
推荐阅读
- asp.net-mvc - 如何将日期时间从 mvc 发送到 web api 作为参数?
- c# - 为什么当我尝试点击操作方法时会出错
- java - 在 Java 中打印数字和非数字
- javascript - 如何使用函数更改 Vue 组件按钮颜色?
- javascript - $(window).on('popstate') 在 IE 中不起作用
- c - 检查给定字符串是否是 C 中的#define
- windows - Powershell 备份脚本
- javascript - 将项目添加到数组篮后的 v-alert 的 setTimeout
- amazon-web-services - 授权访问特定资源
- android - E/RecyclerView:没有附加适配器;使用 FirestoreRecycle 跳过布局