编辑:欢迎标题建议。这可能有一个名字,但我不知道它是什么,也找不到类似的东西。你知道吗
Edit2:我重写了这个问题,试图把它解释得更清楚。在这两个版本中,我认为我已经通过提出一个解释、可复制的示例和我自己的解决方案满足了站点标准。。。如果您能在投票前提出改进建议,我们将不胜感激。你知道吗
我从包含以下三列的系统中输入了用户数据:
%Y-%m-%d %H:%M:%S
格式的时间戳;但是%S=00
适用于所有情况如果用户在同一分钟内输入数据,则仅按时间戳排序是不够的。我们最终得到一个“块”的条目,这些条目的顺序可能正确,也可能不正确。为了说明这一点,我将日期替换为整数,并给出了一个正确且混乱的案例:
我们如何知道数据的顺序正确?当每一行的old
值等于前一行的new
值时(忽略第一行/最后一行中没有可比较的内容)。换句话说:old_i = new_(i-1)
。这将在左侧创建匹配的对角线颜色,而在右侧则是杂乱无章的。你知道吗
其他意见:
old
和new
的值可能相同,因此可以互换date=1
的行),任何解决方案都足够了我的数据集要大得多,因此我的最终解决方案将涉及使用pandas.groupby()
来提供上述函数块。右侧将被传递给函数,我需要返回左侧(或者一些索引/命令将我带到左侧)。你知道吗
下面是一个可复制的示例,使用与上面相同的数据,但是添加了一个group
列和另一个块,这样您就可以看到我的groupby()
解决方案。你知道吗
设置并输入混乱的数据:
import pandas as pd
import itertools
df = pd.DataFrame({'group': ['a', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'b'],
'date': [0, 1, 1, 1, 1, 2, 3, 4, 4],
'old': [1, 8, 2, 2, 5, 5, 4, 10, 7],
'new': [2, 5, 5, 8, 2, 4, 7, 1, 10]})
print(df)
### jumbled: the `new` value of a row is not the same as the next row's `old` value
# group date old new
# 0 a 0 1 2
# 1 a 1 8 5
# 2 a 1 2 5
# 3 a 1 2 8
# 4 a 1 5 2
# 5 a 2 5 4
# 6 b 3 4 7
# 7 b 4 10 1
# 8 b 4 7 10
我写了一个含糊不清的解决方案,要求更优雅的方法。有关我在下面调用的order_rows
函数背后的代码,请参见我的要点here。输出正确:
df1 = df.copy()
df1 = df1.groupby(['group'], as_index=False, sort=False).apply(order_rows).reset_index(drop=True)
print(df1)
### correct: the `old` value in each row equals the `new` value of the previous row
# group date old new
# 0 a 0 1 2
# 1 a 1 2 5
# 2 a 1 5 2
# 3 a 1 2 8
# 4 a 1 8 5
# 5 a 2 5 4
# 6 b 3 4 7
# 7 b 4 7 10
# 8 b 4 10 1
根据networkx
建议更新
请注意,上面的项目符号#2表明,这些不明确的块可以在没有先前引用行的情况下出现。在这种情况下,将起始点作为df.iloc[0]
输入是不安全的。此外,我发现,当使用不正确的起点对图进行种子设定时,它似乎只输出它能够成功排序的节点。请注意,传递了5行,但只返回了4个值。你知道吗
示例:
import networkx as nx
import numpy as np
df = pd.DataFrame({'group': ['a', 'a', 'a', 'a', 'a'],
'date': [1, 1, 1, 1, 1],
'old': [8, 1, 2, 2, 5],
'new': [5, 2, 5, 8, 2]})
g = nx.from_pandas_edgelist(df[['old', 'new']],
source='old',
target='new',
create_using=nx.DiGraph)
ordered = np.asarray(list(nx.algorithms.traversal.edge_dfs(g, df.old[0])))
ordered
# array([[8, 5],
# [5, 2],
# [2, 5],
# [2, 8]])
这是一个图形问题。可以使用
networkx
创建图形,然后使用numpy
进行操作。一个简单的遍历算法,比如depth-first search,将从一个源开始访问所有的边。你知道吗源只是您的第一个节点(即
df.old[0]
)以你为例:
您可以只分配回您的数据帧:
df[['old', 'new']] = ordered
。您可能需要更改一些小细节,例如,如果您的组没有相互连接。但是,如果起点是在group
和date
和上排序的df,则对old_i = new_(i-1)
的依赖关系在组间是受尊重的,那么只需重新分配ordered
数组就可以了。你知道吗不过,我仍然认为你应该调查你的时间戳。我相信这是一个简单的问题,可以通过排序时间戳来解决。在读取/写入文件时,请确保时间戳的精度不会降低。你知道吗
相关问题 更多 >
编程相关推荐