python-3.x 如何将一个标签分配给Pandas Dataframe 的一个组中最小的、另一个组中第二小的和第三个组中第三小的?

6pp0gazn  于 2023-02-06  发布在  Python
关注(0)|答案(2)|浏览(98)

我有下面的数据框,
| 识别号|集团|日期_时间_1|日期时间2|差异|新建_列|
| - ------|- ------|- ------|- ------|- ------|- ------|
| 一百二十三|A类|2021年10月14日15:19|2021年10月14日15时32分|十三|* * 第一次**|
| 一百二十三|A类|2021年10月14日15:19|2021年10月14日15:36|十七|零|
| 一百二十三|A类|2021年10月14日15:19|2021年10月14日15时37分|十八|零|
| 一百二十三|A类|2021年10月14日15:19|2021年10月14日16:29|七十|零|
| 一百二十三|A类|2021年10月14日15:19|2021年10月14日17时04分|一百零五|零|
| 一百二十三|乙|2021年10月14日15:21|2021年10月14日15时32分|十一|零|
| 一百二十三|乙|2021年10月14日15:21|2021年10月14日15:36|十五|* * 第二次**|
| 一百二十三|乙|2021年10月14日15:21|2021年10月14日15时37分|十六|零|
| 一百二十三|乙|2021年10月14日15:21|2021年10月14日16:29|六十八|零|
| 一百二十三|乙|2021年10月14日15:21|2021年10月14日17时04分|一百零三|零|
| 一百二十三|C级|2021年10月14日15:22|2021年10月14日15时32分|十个|零|
| 一百二十三|C级|2021年10月14日15:22|2021年10月14日15:36|十四|零|
| 一百二十三|C级|2021年10月14日15:22|2021年10月14日15时37分|十五|* * 第三次**|
| 一百二十三|C级|2021年10月14日15:23|2021年10月14日16:29|六十七|* * 第三个_A**|
| 一百二十三|C级|2021年10月14日15:48|2021年10月14日17时04分|一百零二|* * 第三个_B**|
| 七八九|A类|2021年10月14日15:19|2021年10月14日15时32分|十三|* * 第一次**|
| 七八九|A类|2021年10月14日15:19|2021年10月14日15:36|十七|零|
| 七八九|乙|2021年10月14日15:21|2021年10月14日15时32分|十一|零|
| 七八九|乙|2021年10月14日15:21|2021年10月14日15:36|十五|* * 第二次**|
| 七八九|C级|2021年10月14日15:22|2021年10月14日15时32分|十个|零|
我正在尝试创建一个新列,该列将"First"分配给组"A"中最小的"Date_Time_2",并将"second"分配给组B中第二小的"Date_Time_2"。类似地,它将"third"分配给组C中第三小的"Date_Time_2"。
我想让它赋值"Third_A","Third_B"等等,一旦循环到达"ID"的最后一个"Group"。所以,一旦到达最后一组"ID",它将分配"第三或3"(因为数据集中只有三个唯一的组)到第三个最低的"Date_Time_2",该"Date_Time_2"未在先前的组中使用,并且如果它将为新的"日期_时间_1 ",它将分配"第三_A "、"第三_B "等等
我已经尝试了下面的代码,但它不工作,

`df.drop('New_Column', axis = 1, inplace = True)
df['New_Column'] = pd.Series()
for i, v in df['Difference'].items():
    a = 0
    b = 1
    diff = df[df['Group'] == df['Group'].unique()[a]]['Difference'].nsmallest(b).min()
    if diff == v:
        df.loc[i, 'New_Column'] = "Yes"
        b = b + 1
    a = a + 1`

任何帮助都是最好的!

f2uvfpb9

f2uvfpb91#

您可以尝试以下操作:

from string import ascii_uppercase as letters

df["Date_Time_2"] = pd.to_datetime(df["Date_Time_2"])
for n, (_, gdf) in enumerate(df.sort_values("Date_Time_2").groupby("Group")):
    nths = gdf.groupby("Date_Time_2", as_index=False).ngroup()
    df.loc[gdf[nths == n].index, "New"] = str(n + 1)
for i, c in zip(gdf[nths > n].index, letters):
    df.at[i, "New"] = f"{n + 1}_{c}"
  • 首先确保列Date_Time_2包含日期时间。
  • 然后,在沿Date_Time_2排序后,按Groupdf分组。
  • 然后在每个组中识别属于n的第Date_Time_2子组(从0开始)的索引,并在相应的New列行上设置n + 1
  • 然后取最后一组,将字母值添加到New列。

也许你得把最后一部分换成

for k, c in zip(range(n + 1, nths.max() + 1), letters):
    df.loc[gdf[nths == k].index, "New"] = f"{n + 1}_{c}"

字母值是否也应该分组。
问题中样本的结果:

ID Group       Date_Time_1         Date_Time_2  Difference New_Column  New
0   123     A  14-10-2021 15:19 2021-10-14 15:32:00          13      First    1
1   123     A  14-10-2021 15:19 2021-10-14 15:36:00          17        NaN  NaN
2   123     A  14-10-2021 15:19 2021-10-14 15:37:00          18        NaN  NaN
3   123     A  14-10-2021 15:19 2021-10-14 16:29:00          70        NaN  NaN
4   123     A  14-10-2021 15:19 2021-10-14 17:04:00         105        NaN  NaN
5   123     B  14-10-2021 15:21 2021-10-14 15:32:00          11        NaN  NaN
6   123     B  14-10-2021 15:21 2021-10-14 15:36:00          15     Second    2
7   123     B  14-10-2021 15:21 2021-10-14 15:37:00          16        NaN  NaN
8   123     B  14-10-2021 15:21 2021-10-14 16:29:00          68        NaN  NaN
9   123     B  14-10-2021 15:21 2021-10-14 17:04:00         103        NaN  NaN
10  123     C  14-10-2021 15:22 2021-10-14 15:32:00          10        NaN  NaN
11  123     C  14-10-2021 15:22 2021-10-14 15:36:00          14        NaN  NaN
12  123     C  14-10-2021 15:22 2021-10-14 15:37:00          15      Third    3
13  123     C  14-10-2021 15:23 2021-10-14 16:29:00          67    Third_A  3_A
14  123     C  14-10-2021 15:48 2021-10-14 17:04:00         102    Third_B  3_B
15  789     A  14-10-2021 15:19 2021-10-14 15:32:00          13      First    1
16  789     A  14-10-2021 15:19 2021-10-14 15:36:00          17        NaN  NaN
17  789     B  14-10-2021 15:21 2021-10-14 15:32:00          11        NaN  NaN
18  789     B  14-10-2021 15:21 2021-10-14 15:36:00          15     Second    2
19  789     C  14-10-2021 15:22 2021-10-14 15:32:00          10        NaN  NaN

如果必须为每个ID组完成整个过程,则可以尝试

...
for _, df_id in df.sort_values("Date_Time_2").groupby("ID"):
    for n, (_, gdf) in enumerate(df_id.groupby("Group")):
        nths = gdf.groupby("Date_Time_2", as_index=False).ngroup()
        df.loc[gdf[nths == n].index, "New"] = str(n + 1)
    for i, c in zip(gdf[nths > n].index, letters):
        df.at[i, "New"] = f"{n + 1}_{c}"

而不是。

j5fpnvbx

j5fpnvbx2#

首先,确保你正确地读取csv值。这意味着日期时间值应该被正确地解释,例如。

date_parse = lambda x : pd.to_datetime(x, format="%d-%m-%Y %H:%M")
df = pd.read_csv('filename.csv', parse_dates=['Date_Time_1','Date_Time_2'], date_parser= date_parse)

如果您已经有了 Dataframe ,您可以使用以下代码来解析 Dataframe 中日期时间对象,

df['Date_Time_2'] = pd.to_datetime(df['Date_Time_2'], format="%d-%m-%Y %H:%M")
df['Date_Time_2'] = pd.to_datetime(df['Date_Time_2'], format="%d-%m-%Y %H:%M")

现在,只需在不同的组中迭代,并在排序列表中过滤出date_time_2列,最后取出适当的索引,例如,对于组“A”,取出“0”索引,对于组“B”,取出“1”索引......,选择适当的 Dataframe 并更新新列中的值

df['New_Column'] = 'NA'
for index, group in enumerate(df['Group'].unique()):
    unqiue_time = df[df['Group'] == group]['Date_Time_2'].unique()[index]
    df.loc[(df['Group'] == group) & (df['Date_Time_2'] == unqiue_time), 'New_Column'] = index
print(df)

注意:添加数字要容易得多,例如“first”、“second”,如果需要,可以创建一个新列表,并从索引中赋值,如下所示

df['New_Column'] = 'NA'
number_as_string = ['first', 'second', 'third']
for index, group in enumerate(df['Group'].unique()):
    unqiue_time = df[df['Group'] == group]['Date_Time_2'].unique()[index]
    df.loc[(df['Group'] == group) & (df['Date_Time_2'] == unqiue_time), 'New_Column'] = number_as_string[index]
print(df)

相关问题