首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用Python和Pandas的状态计算器

使用Python和Pandas的状态计算器
EN

Stack Overflow用户
提问于 2018-07-03 04:46:40
回答 2查看 130关注 0票数 -1

我正在练习Pandas,Lambda函数,并且面临着一项艰巨的任务。我已经有了一个“形式上”正确的解决方案,但效率绝对低下。

这就是问题:

我有一个类似如下的Pandas DataFrame df (在本文末尾生成此示例的代码):

代码语言:javascript
复制
     id  type
0  1003     G
1  1003     A
2  1002     T
3  1002     A
4  1001     A
5  1003     A
6  1002     G
7  1003     A
8  1001     T
9  1001     A

预期输出:每个不同的类型(A、C、G、T)都有一个新列,其中包含在表中显示的最后一行中具有该类型的唯一in的数量。

一种可能的输出是这样的(编辑以匹配期望的结果):

代码语言:javascript
复制
     id  num_A  num_C  num_G  num_T type
0  1003      0      0      1      0    G
1  1003      1      0      0      0    A
2  1002      1      0      0      1    T
3  1002      2      0      0      0    A
4  1001      3      0      0      0    A
5  1003      3      0      0      0    A
6  1002      2      0      1      0    G
7  1003      2      0      1      0    A
8  1001      1      0      1      1    T
9  1001      2      0      1      0    A

为了实现这个目标,我做了以下工作(如果将输出与上面的表进行比较,会发现不能正常工作):

  1. 定义了一个临时DataFrame tmp,用于存储所有可能in的状态(在此示例中,最多有9个in):

id type_A type_C type_G type_T 0 1001 0 0 0 1 1002 0 0 0 2 1003 0 0 0 3 1004 0 0 0 4 1005 0 0 0 5 1006 0 0 00 6 1007 0 0 0 7 1008 0 0 0 8 1009 0 0 0

  • 定义了一个迭代循环,该循环检查df中每行的类型,然后相应地更新tmp DataFrame:

的状态

代码如下:

代码语言:javascript
复制
for df_row in range(0, df.shape[0]):
    if df.type[df_row] == 'A':
        for tmp_row in range(0, tmp.shape[0]):
            if tmp.id[tmp_row] == df.id[df_row]:
                tmp.type_A[tmp_row] = 1
        df.num_A[df_row] = tmp.type_A.sum()
    if df.type[df_row] == 'C':
        for tmp_row in range(0, tmp.shape[0]):
            if tmp.id[tmp_row] == df.id[df_row]:
                tmp.type_C[tmp_row] = 1
        df.num_C[df_row] = tmp.type_C.sum()
    if df.type[df_row] == 'G':
        for tmp_row in range(0, tmp.shape[0]):
            if tmp.id[tmp_row] == df.id[df_row]:
                tmp.type_G[tmp_row] = 1
        df.num_G[df_row] = tmp.type_G.sum()
    if df.type[df_row] == 'T':
        for tmp_row in range(0, tmp.shape[0]):
            if tmp.id[tmp_row] == df.id[df_row]:
                tmp.type_T[tmp_row] = 1
        df.num_T[df_row] = tmp.type_T.sum()

我想了解的是,如果使用Lambda函数或不同的方法,是否有可能得到更快的结果,这在性能方面也更好。

要生成像我这样的示例DataFrame,您可以使用以下代码(也欢迎关于如何调整此代码的建议,以便我可以了解更多):

代码语言:javascript
复制
df = pd.DataFrame({'id': np.random.randint(1001, 1004, size=10), \
                   'type_tmp': np.random.randint(1, 4, size=10), \
                   'type': '', \
                   'num_G': 0, 'num_A': 0, 'num_T': 0, 'num_C': 0})
for r in range(0, df.shape[0]):
    if df.type_tmp[r] == 1:
        df.type[r] = 'G'
    if df.type_tmp[r] == 2:
        df.type[r] = 'A'
    if df.type_tmp[r] == 3:
        df.type[r] = 'T'
    if df.type_tmp[r] == 4:
        df.type[r] = 'C'
df = df.drop(columns='type_tmp')

临时DataFrame的定义如下:

代码语言:javascript
复制
tmp = pd.DataFrame({'id': np.arange(1001, 1010), 'type_A': 0, 'type_C': 0, 'type_G': 0, 'type_T': 0})

感谢您的宝贵时间。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-04 00:00:44

这个问题的修订版与原始版本有很大的不同,我们可以简单地旋转和向前填充来获得任何行的状态,然后使用value_counts来获得数字:

代码语言:javascript
复制
state = df.reset_index().pivot(index="index", columns="id").ffill()
counts = state.apply(pd.value_counts, axis=1).reindex(["A", "C", "G", "T"], axis=1)
counts = counts.fillna(0).astype(int)
out = df.join(counts)

这给了我

代码语言:javascript
复制
In [193]: out
Out[193]: 
     id type  A  C  G  T
0  1003    G  0  0  1  0
1  1003    A  1  0  0  0
2  1002    T  1  0  0  1
3  1002    A  2  0  0  0
4  1001    A  3  0  0  0
5  1003    A  3  0  0  0
6  1002    G  2  0  1  0
7  1003    A  2  0  1  0
8  1001    T  1  0  1  1
9  1001    A  2  0  1  0
票数 1
EN

Stack Overflow用户

发布于 2018-07-03 05:13:31

到目前为止,要从数据帧中找到唯一的一组类型,可以从开始到每一行取一段数据帧,然后强制将其放入一个集合中,并取其长度。如果您已经使用适当的列(全为0)设置了数据帧,则可以将该集合的长度插入到正确的位置:

代码语言:javascript
复制
for index, row in df.iterrows():
    l = len(set(df['type'].head(index)))
    t = row['type']
    df['num_'.format(t)][index] = t

让我知道这是否有帮助,我可以添加更多,如果你需要。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51143508

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档