DF:
geneName HumanNumber
AHHD 585447
GDFGRE 585447
HFHFR 585447
REWEGD 585447
FDSDD 585447
AHHD 42334
GHRG 42334
REWEGD 42334
FDSDD 42334
...
HFHFR 585447
GDFGRE 585447
AHHD 585447
REWEGD 585447
FDSDD 585447
...
HumanNumber
是HumanID,geneName
是经过检查的基因。在数据框中,我有80k人。每个人可以检查120-200个基因。
U可以看到一个人可以被检查2次或更多次。在此示例中,我humanID 585447
在两个不同的机构进行了两次检查。因此,需要将其分析为两个不同的人,但是我不能只更改HumanNumber
-因为它需要与源文件相同才能进行后续处理。
所以我需要为所有样品创建分析。复制的内容不能在同一结果文件中。它们需要分开。
所以我的想法是:
-添加新列-由DF循环的每个indicationCol
的{{1}}。
-然后df看起来会:
HumanNumber
现在我只能按ID提取HumanNumbers,如果df不是唯一的,则可以用geneName HumanNumber indicationCol
AHHD 585447 1
GDFGRE 585447 1
HFHFR 585447 1
REWEGD 585447 1
FDSDD 585447 1
AHHD 42334 2
GHRG 42334 2
REWEGD 42334 2
FDSDD 42334 2
...
HFHFR 585447 3
GDFGRE 585447 3
AHHD 585447 3
REWEGD 585447 3
FDSDD 585447 3
...
提取第二个,然后将其丢给另一个df。
df
indicationCol
df_duplicates:
geneName HumanNumber indicationCol
AHHD 585447 1
GDFGRE 585447 1
HFHFR 585447 1
REWEGD 585447 1
FDSDD 585447 1
AHHD 42334 2
GHRG 42334 2
REWEGD 42334 2
FDSDD 42334 2
...
所以我写了一个代码:
HFHFR 585447 3
GDFGRE 585447 3
AHHD 585447 3
REWEGD 585447 3
FDSDD 585447 3
这是可行的(尽管我从熊猫那里收到了复制警告),但时间太长了。 name = '585447'
a = 0
df['indicationCol'] = 99999999
df= df.copy()
for i in range(len(df)):
if df[4].iloc[i] == name:
df['indicationCol'].iloc[i] = a
else:
a = a+1
name = df[4].iloc[i]
df['wskaznik'].iloc[i] = a
20分钟后。整个df有15,012,022行。
所以..我该怎么做才能升级我的代码。我希望是解决这个问题的更好方法,我只是不知道。
有人可以帮助我吗?
答案 0 :(得分:2)
如果您希望这种按时间顺序表示重复的方式,我们可以使用diff
和cumsum
:
df['indicationCol'] = df['HumanNumber'].diff().fillna(0).ne(0).cumsum().add(1)
或将shift
与cumsum
:
df['indicationCol'] = df['HumanNumber'].ne(df['HumanNumber'].shift()).cumsum()
输出
geneName HumanNumber indicationCol
0 AHHD 585447 1
1 GDFGRE 585447 1
2 HFHFR 585447 1
3 REWEGD 585447 1
4 FDSDD 585447 1
5 AHHD 42334 2
6 GHRG 42334 2
7 REWEGD 42334 2
8 FDSDD 42334 2
9 HFHFR 585447 3
10 GDFGRE 585447 3
11 AHHD 585447 3
12 REWEGD 585447 3
13 FDSDD 585447 3
我建议使用GroupBy
上的HumanNumber
和新列indicationCol
来访问每个唯一组:
for _, grp in df.groupby(['HumanNumber', 'indicationCol'], sort=False):
print(grp, '\n')
geneName HumanNumber indicationCol
0 AHHD 585447 1
1 GDFGRE 585447 1
2 HFHFR 585447 1
3 REWEGD 585447 1
4 FDSDD 585447 1
geneName HumanNumber indicationCol
5 AHHD 42334 2
6 GHRG 42334 2
7 REWEGD 42334 2
8 FDSDD 42334 2
geneName HumanNumber indicationCol
9 HFHFR 585447 3
10 GDFGRE 585447 3
11 AHHD 585447 3
12 REWEGD 585447 3
13 FDSDD 585447 3
答案 1 :(得分:1)
对您问题的书面答复 您可以通过计数器col来完成此过程:
df['indicatorCol'] = (df
.duplicated()
.to_frame()
.groupby([df.HumanNumber, df.geneName])
.apply(lambda x: x.cumsum())
结果:
geneName HumanNumber indicatorCol
0 AHHD 585447.0 1
1 GDFGRE 585447.0 1
2 HFHFR 585447.0 1
3 REWEGD 585447.0 1
4 FDSDD 585447.0 1
5 AHHD 42334.0 0
6 GHRG 42334.0 0
7 REWEGD 42334.0 0
8 FDSDD 42334.0 0
10 HFHFR 585447.0 2
11 GDFGRE 585447.0 2
12 AHHD 585447.0 2
13 REWEGD 585447.0 2
14 FDSDD 585447.0 2
更快捷的方法
您可以使用pandas.DataFrame.duplicated()
完成相同的目标,这实际上是重复的指标。
df[df.duplicated(keep='first')] # First to get the first entry and label others as duplications
geneName HumanNumber
10 HFHFR 585447.0
11 GDFGRE 585447.0
12 AHHD 585447.0
13 REWEGD 585447.0
14 FDSDD 585447.0
unique_df = df[~df.duplicated(keep='first')] # Unique first occurances
duplicated_df = df[df.duplicated(keep='first')] #Duplicates of Unique
您还可以使用df[~df.duplicated(keep='first')]
与第一个DataFrame
的重复值。
对keep
argument的一些解释:
保持:{'first','last',False},默认为'first'
- first:将第一个重复项标记为“ True”。
- last:将最后一次出现的重复项标记为True。
- False:将所有重复项标记为True。