我正在寻找一种有效的方法来计算新的列数据(对于每一行),使用其他行上可能存在的信息。你知道吗
下面是一个示例子集:
df = pd.DataFrame({'baseSeq': {0: 'ADTPICR', 1: 'ADTPICR', 2: 'AVALFAED', 3: 'AVALFAED', 4: 'AVALFAED', 5: 'AVALFAED', 6: 'AVALFAED', 7: 'AVALFAED'}, 'modSeq': {0: 'ADT[+16]PICR', 1: 'ADTPICR', 2: 'AVALFAED[+16]', 3: 'AVALFAE[+16]D', 4: 'AVALFAED', 5: 'AVALFAED[-30]', 6: 'AVALFAED', 7: 'AVALFAED'}, 'charge': {0: 2, 1: 2, 2: 2, 3: 2, 4: 2, 5: 3, 6: 3, 7: 4}, 'modType': {0: 'hydoxy', 1: 'UNMOD', 2: 'hydroxy', 3: 'hydroxy', 4: 'UNMOD', 5: 'decarbox', 6: 'UNMOD', 7: 'UNMOD'}, 'area_0': {0: 1862, 1: 22737, 2: 40060, 3: 40131, 4: 21962, 5: 12, 6: 21885, 7: 2116}, 'area_25': {0: 2472, 1: 30966, 2: 2423, 3: 2407, 4: 34387, 5: 16, 6: 35444, 7: 3072}, 'area_50': {0: 3015, 1: 24660, 2: 3553, 3: 3577, 4: 29860, 5: 40, 6: 33511, 7: 2974}})
baseSeq modSeq charge modType area_0 area_25 area_50
0 ADTPICR ADT[+16]PICR 2 hydoxy 1862 2472 3015
1 ADTPICR ADTPICR 2 UNMOD 22737 30966 24660
2 AVALFAED AVALFAED[+16] 2 hydroxy 40060 2423 3553
3 AVALFAED AVALFAE[+16]D 2 hydroxy 40131 2407 3577
4 AVALFAED AVALFAED 2 UNMOD 21962 34387 29860
5 AVALFAED AVALFAED[-30] 3 decarbox 12 16 40
6 AVALFAED AVALFAED 3 UNMOD 21885 35444 33511
7 AVALFAED AVALFAED 4 UNMOD 2116 3072 2974
具体来说,我想为每个修改序列(实际上是每一行)的“未修改分数”计算新的列,然后将其扩展到多个“区域”列。你知道吗
fracumond=(1-(area\u modified/(area\u modified+area\u unmodified)))
“area\u unmodified”值必须来自不同的行,因此我似乎无法找到使用df.concat()
或df.insert()
这样的函数来实现这一点的方法。
正确的“area_unmodified”值是从共享相同的“baseSeq”和“charge”值的行中确定的,但没有任何修改(为了方便起见,我包括了一列“modType”)。你知道吗
我不必为未修改的行计算fracumond,但我不想从结果输出中删除这些行(保留它们只会得到fracumond=0.5,这很好)。你知道吗
有时有些行找不到未修改的版本(未显示),但我忽略了这些行,因为我知道我更喜欢在单独的帖子中提出次要问题,而且我可以在Excel中手动筛选这些问题。你知道吗
我一直在做这样的事情,在每一行循环:
for X in df.columns[df.columns.str.contains('area')].tolist():
df[X.replace('area', 'fracUnmod')] = ''
for row in df.index:
for X in df.columns[df.columns.str.contains('area')].tolist():
Y = X.replace('area', 'fracUnmod')
df[Y].iloc[row] = (1 - ((df.iloc[row][X]) / ((df.iloc[row][X]) + (df[(df.baseSeq==df.iloc[row].baseSeq) & (df.charge==df.iloc[row].charge) & (df.baseSeq==df.modSeq)][X].item()))))
这是可行的,但是对于我的完整数据集(650行表示“row”循环通过,10个“area”列表示“X”循环通过)需要很长时间(大约10分钟)。你知道吗
我还提出了一个讨厌的“SettingWithCopyWarning”——我是否可以通过在最后一行的“链式赋值”后面附加.ascopy()
来避免这个问题?我一直没能弄明白。你知道吗
我已经读过好几遍了,只要有可能就应该避免循环,所以我猜这就是问题所在。 有没有更干净更快的方法?你知道吗
“modSeq”和“charge”的每个组合都是唯一的,所以也许我想用df.groupby()
或df.merge()
做些什么,并使用临时DF?你知道吗
我经常遇到这种情况,所以我想学习如何在不使用循环的情况下做这类事情(或者至少提高速度)。你知道吗
如果我们创建一些临时列,就可以矢量化您的数学运算,这将大大减少时间。之后我们可以删除临时列。你知道吗
使用您给出的示例,它看起来是这样的:
df
开始,看起来像这样:创建所有“区域”列的列表:
area_cols = df.columns[df.columns.str.contains('area')].tolist()
下面5行代码创建一个临时df,其中包含每个
baseSeq
/charge
组合的未修改的区域:以下是此时临时df的样子:
然后,我们将这个临时数据帧连接回主数据帧,以便让列为每个
baseSeq
/charge
组合显示适当数量的未修改区域:df = df.join(temp_df, on=['baseSeq', 'charge'])
此时,我们的数据帧如下所示:
为了清理这些内容,我们先删除显示未添加区域的临时列,然后删除临时数据框。你知道吗
df = df.drop(['unmod_' + c for c in area_cols], axis=1)
del(temp_df)
最后的数据帧如下所示:
这与原始嵌套for循环生成的输出相同。但希望能快得多。你知道吗
相关问题 更多 >
编程相关推荐