gpt4 book ai didi

python - 从数据框中的组中删除在特定列中具有最小值的行

转载 作者:行者123 更新时间:2023-11-28 18:12:26 25 4
gpt4 key购买 nike

我在 csv 文件中有一个数据集。我使用 pandas 作为数据框导入了它。然后我根据我命名为 Vf 的列从最小到最大对我的数据进行排序。

从这里我的代码试图做什么:将排序后的数据帧 (DF) 分组为 11 个一组。计算每组中相应的最小值和最大值之间的差异。遍历每个组并检查任何组的最小值和最大值之间的差异是否大于 0.2。如果任何组都满足此条件,我希望代码从原始数据框中删除包含该组最小值的数据行。然后再次对数据框进行排序和分组,减去该行。再次遍历每个组,检查最小值和最大值之间的差异。它应该继续这样做,直到它遍历每个组并发现它们的最小值和最大值之间的差异都不大于 0.2。

据我所知,现在我的代码就是这样做的。但是当我想要它时它不会停止,即当所有组的最小值和最大值之间的差异小于 0.2 时,它不会停止。此外,此时它实际上似乎将行添加回原始数据框中。

这是代码。请注意,我已将其设置为仅通过我数据中的前 2 组。另请注意,我的 for 循环中的行要求它打印语句和排序数据框的形状。这一切都是为了提供用于调试目的的信息。

def celling():
import numpy as np
import pandas as pd
Data = input("Name of File: ")
DF = pd.read_csv("Y:\CHRIS\{}.csv".format(Data), skiprows = 20, names = ["Serial","Bin","Ir","Vf"])

def sort(Data):
SortedDF = Data.sort_values(by='Vf')
GroupedDF = SortedDF.groupby(np.arange(len(SortedDF))//11)
GroupMax = GroupedDF["Vf"].max()
GroupMin = GroupedDF["Vf"].min()
GroupDiff = GroupMax - GroupMin
GroupMinIndices = GroupedDF["Vf"].idxmin()
#sort(DF)
for i in range(2):

if GroupDiff[i] > 0.2:
DF = Data[Data.index != GroupMinIndices[i]]
print("Group {} was bad.".format(i))
print(SortedDF.shape)
sort(DF)
else:
print("Group {} is good.".format(i))
print(SortedDF.shape)
sort(DF)

这是原始数据框的示例:

        Serial  Bin       Ir     Vf
0 1 1.0 0.00161 170.7
1 2 1.0 0.00157 173.3
2 3 1.0 0.00169 171.0
3 4 1.0 0.00145 172.7
4 5 1.0 0.00170 171.4
5 6 1.0 0.00160 172.6
6 7 1.0 0.00180 172.4
7 8 1.0 0.00169 172.1
8 9 1.0 0.00147 170.9
9 10 1.0 0.00151 172.3
10 11 1.0 0.00142 171.8
11 12 1.0 0.00168 171.5

这是按 Vf 排序的数据帧示例:

    Serial  Bin       Ir     Vf
477 478 1.0 0.00180 170.0
359 360 1.0 0.00139 170.1
247 248 1.0 0.00197 170.1
575 576 1.0 0.00159 170.2
267 268 1.0 0.00178 170.2
178 179 1.0 0.00277 170.3
82 83 1.0 0.00145 170.3
574 575 1.0 0.00162 170.3
97 98 1.0 0.00190 170.3
399 400 1.0 0.00172 170.4
21 22 1.0 0.00166 170.4
67 68 1.0 0.00176 170.5
103 104 1.0 0.00154 170.5
553 554 1.0 0.00169 170.5
533 534 1.0 0.00167 170.5
177 178 1.0 0.00160 170.5
35 36 1.0 0.00150 170.5
186 187 1.0 0.00165 170.5
363 364 1.0 0.00172 170.6
487 488 1.0 0.00159 170.6

所以理想情况下,代码在这里应该做的是检查这个示例的前 11 行,注意这 11 行中的最大值和最小值之间的差值大于 0.2,然后从第一行中删除具有最小值的行11,在这种情况下,将是序列号为 11 的行。 478. 然后它应该重新组合数据,上面示例中的第 2-12 行现在构成第一组 11。然后它应该注意到最小/最大差异仍然大于 0.2 并重新开始。代码完成后,下面应该是上述示例中的第一组 11

178    179  1.0  0.00277  170.3
82 83 1.0 0.00145 170.3
574 575 1.0 0.00162 170.3
97 98 1.0 0.00190 170.3
399 400 1.0 0.00172 170.4
21 22 1.0 0.00166 170.4
67 68 1.0 0.00176 170.5
103 104 1.0 0.00154 170.5
553 554 1.0 0.00169 170.5
533 534 1.0 0.00167 170.5
177 178 1.0 0.00160 170.5

这是我的代码目前的结果:

Group 0 was bad.
(643, 4)
Group 0 was bad.
(642, 4)
Group 0 was bad.
(641, 4)
Group 0 was bad.
(640, 4)
Group 0 was bad.
(639, 4)
Group 0 is good.
(638, 4)
Group 1 was bad.
(638, 4)
Group 0 is good.
(637, 4)
Group 1 was bad.
(637, 4)
Group 0 is good.
(636, 4)
Group 1 was bad.
(636, 4)
Group 0 is good.
(635, 4)
Group 1 was bad.
(635, 4)
Group 0 is good.
(634, 4)
Group 1 was bad.
(634, 4)
Group 0 is good.
(633, 4)
Group 1 is good.
(633, 4)
(634, 4)
(635, 4)
(636, 4)
(637, 4)
(638, 4)
(639, 4)
Group 1 is good.
(639, 4)
(640, 4)
Group 1 is good.
(640, 4)
(641, 4)
Group 1 is good.
(641, 4)
(642, 4)
Group 1 is good.
(642, 4)
(643, 4)
Group 1 is good.
(643, 4)
(643, 4)

请注意,当它读取到第 0 组的最大值和最小值之差大于 0.2 时,它是如何不断删除行的。然后它移动到第 1 组。当它读到第 1 组中的最大/最小差异大于 0.2 时,它删除该行并返回到 for 循环的开始(我知道这个效率不高)。但是,请注意,理论上它应该在读到第 0 组良好然后第 1 组良好时立即停止,但事实并非如此。请注意,在它读取它们之后它们都很好,它似乎开始将行添加回数据框中。

如果有人能解释为什么我的代码这样做,或者解释我的代码在做什么,如果它没有这样做,我们将不胜感激。请注意,我是 python 的新手,所以请多关照! :)

最佳答案

这是一个棘手的问题,所以让我们从重述开始。

  1. 排序 使用 Vf 列的数据
  2. 分组 连续 11 行并找到最小-最大差值超过 0.2 的第一组。
  3. 数据从该组开始分成两部分,第一部分是好的部分,第二部分是坏的 并要求从开头删除行。
  4. 删除部分开始的行,直到VfVf.shift(-10 )不超过0.2
  5. 重复这些步骤(group-split-remove)直到一个split有一个空的bad part
  6. 加入所有好的部分以获得最终结果
  7. (可选)为最终结果分配一个group id

创建示例排序数据框:

df = pd.read_table(io.StringIO("""    Serial  Bin       Ir     Vf
477 478 1.0 0.00180 170.0
359 360 1.0 0.00139 170.1
247 248 1.0 0.00197 170.1
575 576 1.0 0.00159 170.2
267 268 1.0 0.00178 170.2
178 179 1.0 0.00277 170.3
82 83 1.0 0.00145 170.3
574 575 1.0 0.00162 170.3
97 98 1.0 0.00190 170.3
399 400 1.0 0.00172 170.4
21 22 1.0 0.00166 170.4
67 68 1.0 0.00176 170.5
103 104 1.0 0.00154 170.5
553 554 1.0 0.00169 170.5
533 534 1.0 0.00167 170.5
177 178 1.0 0.00160 170.5
35 36 1.0 0.00150 170.5
186 187 1.0 0.00165 170.5
363 364 1.0 0.00172 170.6
487 488 1.0 0.00159 170.6"""), sep='\s+')

以下是辅助函数:

def grouper(frame):
return np.arange(len(frame)) // 11

def remove(frame):
return (
(frame.Vf.shift(-10).fillna(frame.Vf.max()) - frame.Vf) < 0.2
).cumsum() > 0

def split_df(frame):
return frame.groupby(
grouper(frame)
).Vf.transform(
lambda x: (x.max() - x.min()) > 0.2
).cumsum() > 0

column.cumsum() > 0 其中列具有 bool 类型,在遇到第一个真值后过滤所有行,包括为真的行。

下面的函数实现了上面的递归逻辑(借助上面定义的一些辅助函数)

def group_split_remove(frame):
temp = frame[split_df(frame)]
if len(temp) == 0:
return frame
return pd.concat([frame[~split_df(frame)], group_split_remove(temp[remove(temp)])])

现在,python 中的递归并不总是最好的策略,因此,如果上述方法不够快或达到最大递归深度,请将其重新表述为 while 循环。但是,我相信递归公式在这种情况下更具可读性

使用您的示例(已排序)数据,group_split_remove(df) 返回以下数据框:

     Serial  Bin       Ir     Vf
178 179 1.0 0.00277 170.3
82 83 1.0 0.00145 170.3
574 575 1.0 0.00162 170.3
97 98 1.0 0.00190 170.3
399 400 1.0 0.00172 170.4
21 22 1.0 0.00166 170.4
67 68 1.0 0.00176 170.5
103 104 1.0 0.00154 170.5
553 554 1.0 0.00169 170.5
533 534 1.0 0.00167 170.5
177 178 1.0 0.00160 170.5
35 36 1.0 0.00150 170.5
186 187 1.0 0.00165 170.5
363 364 1.0 0.00172 170.6
487 488 1.0 0.00159 170.6

如您所见,前 11 行与您的预期输出完全匹配。

最后的可选步骤是分配一个 group_id,可以按如下方式完成:

res['group_id'] = grouper(res)

关于python - 从数据框中的组中删除在特定列中具有最小值的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50344778/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com