python - 在循环中创建唯一 ID
问题描述
我有一个数据集,其中一列如下。我想根据以下条件创建一个新列
我知道下面的代码将满足条件
np.where((df['col']==1),((df['col'] != df1['col'].shift(1)).astype(int).cumsum()),0)
但是,如果我将代码放在某个循环中,我不希望cumsum()
再次从 1 开始。它最终会创建重复项。我怎样才能克服这个?
是否可以为该特定条件生成随机数?所以如果它在循环内,我仍然会创建随机数而不是重复的
column_name
1
0
0
1
1
1
1
0
0
1
column_name -- ID
1 -- 1
0 -- 0
0 -- 0
1 -- 2
1 -- 2
1 -- 2
1 -- 2
0 -- 0
0 -- 0
1 -- 3
解决方案
这是获取顺序 int ID 的简单方法:
# setup environment
import pandas as pd
import numpy as np
np.random.seed(13)
df = pd.DataFrame({'col': [1, 0, 0, 1, 1, 1, 1, 0, 0, 1]})
# create masks for use in later updates
msk_one = df['col'] == 1
msk_first = df['col'] != df['col'].shift()
# mark each time a new series of 1s begins with a True
df['ID'] = msk_one & msk_first
# add up the Trues to get sequential ids
df['ID'] = df['ID'].cumsum()
# drop ids on the False rows
df.loc[~msk_one, 'ID'] = 0
print(df)
# col ID
# 0 1 1
# 1 0 0
# 2 0 0
# 3 1 2
# 4 1 2
# 5 1 2
# 6 1 2
# 7 0 0
# 8 0 0
# 9 1 3
要将这些顺序 ID 转换为随机 ID,您可以执行以下操作:
# create conversion dict mapping from sequential to random IDS
ids = df['ID'].unique()
# ignore zeros because we want to manually map them to themselves
ids = ids[ids != 0]
random_ids = np.random.choice(ids, len(ids), replace=False)
sequential_to_random = {non_random_id: random_id for non_random_id, random_id in zip(ids, random_ids)}
sequential_to_random[0] = 0
# convert the IDs to random ints
df['ID'] = df['ID'].apply(lambda x: sequential_to_random[x])
print(df)
# col ID
# 0 1 2
# 1 0 0
# 2 0 0
# 3 1 1
# 4 1 1
# 5 1 1
# 6 1 1
# 7 0 0
# 8 0 0
# 9 1 3
希望这可以帮助!
推荐阅读
- python - Pandas pivot_table 发出关于在日期类型的数据集上使用边距时推断 datetime64 的 FutureWarning
- flutter - 购买后不调用函数
- android - 布局检查器未显示可组合树
- html - 服务器代码是持续运行还是仅在用户发出请求时运行?
- bash - 安装了两个版本的 bash,来自终端的关于我正在使用哪个版本的信息冲突
- android-studio - 检查 URL 连接 Android Studio
- html - SVG 中的等宽字体具有可变宽度字形
- javascript - child() 不是函数图片上传 firebaseSDK Ver9 for Web (JavaScript)
- python - 事件循环关闭 discord.py
- c++ - 将基类指针(实际上指向派生类)转换为不同派生类的指针(从同一个基类派生)