如何一次读取pandas数据帧的两行和两列并对这些行/列值应用条件?

时间:2017-03-15 17:40:39

标签: python pandas if-statement dataframe conditional-statements

我想在pandas Dataframe中一次读取两行和两列,然后在zip vs. product的两个行/列矩阵之间应用条件相关的pandas Dataframe字符串。

import pandas as pd
import itertools as it
from itertools import product

cond_mcve = pd.read_csv('condition01.mcve.txt', sep='\t')

  alfa  alfa_index beta  beta_index delta  delta_index
0  a,b          23  c,d          36   a,c           32
1  a,c          23  b,e          37   c,d           32
2  g,h          28  d,f          37   e,g           32
3  a,b          28  c,d          39   a,c           34
4  c,e          28  b,g          39   d,k           34
  • 此处 alfa,beta和delta 是字符串值,它们有自己的相应索引。

  • 如果它们具有相同的索引值,我想创建两个相邻字符串的zip(按行)。 因此,对于alfa column的前两行,输出应为aa,cb,因为两行的alfa_index为23

  • 但是,对于alfa列的第2行和第3行,两个索引值不同(23和28)因此,输出应该是字符串的乘积,即输出:ga,gc,ha, HC

这是我在心理上想到的事情: 而且,我希望我能非常清楚地解释这个问题。

# write a function
def some_function():
    read_two columns at once (based on prefix similarity)

    then:
    if two integer_index are same:
        zip(of strings belonging to that index)

    if two integer index are different:
        product(of strings belonging to that index)

# take this function and apply it to pandas dataframe:
cond_mcve_updated = cond_mcve+cond_mcve.shift(1).dropna(how='all').applymap(some_function)

这里shift能够一次读取两行,因此我解决了一次读取两行的问题。 但是,在阅读两个专栏并实施条件时,我遇到了其他问题:

  • 在pandas数据框中一次读取两列(基于前缀相似性)。
  • 将这些列分开以比较索引值(整数)
  • 根据条件应用zip与产品

预期的最终输出将是:

   alfa          alfa_index    beta             beta_index    delta  delta_index
1  aa,cb         23            bc,bd,ec,ed      37            ca,dc           32
2  ga,gc,ha,hc   28            db,fe            37            ec,gd           32
same for other line.....

# the first index(i.e 0 is lost) but that's ok. I can work it out using `head/tail` method in pandas.

1 个答案:

答案 0 :(得分:1)

这是实现结果的一种方法。此函数使用shiftconcatapply将数据运行到一个函数中,该函数可以根据匹配的_index值执行prod / sum事务。

<强>代码:

import itertools as it

def crazy_prod_sum_thing(frame):
    # get the labels which do not end with _index
    labels = [(l, l + '_index')
              for l in frame.columns.values if not l.endswith('_index')]

    def func(row):
        # get row n and row n-1
        front = row[:len(row) >> 1]
        back = row[len(row) >> 1:]

        # loop through the labels
        results = []
        for l, i in labels:
            x = front[l].split(',')
            y = back[l].split(',')
            if front[i] == back[i]:
                results.append(x[0] + y[0] + ',' + x[1] + x[1])
            else:
                results.append(
                    ','.join([x1 + y1 for x1, y1 in it.product(x, y)]))

        return pd.Series(results)

    # take this function and apply it to pandas dataframe:
    df = pd.concat([frame, frame.shift(1)], axis=1)[1:].apply(
        func, axis=1)

    df.rename(columns={i: x[0] + '_cpst' for i, x in enumerate(labels)},
              inplace=True)
    return pd.concat([frame, df], axis=1)

测试代码:

import pandas as pd
from io import StringIO
data = [x.strip() for x in """
      alfa  alfa_index beta  beta_index delta  delta_index
    0  a,b          23  c,d          36   a,c           32
    1  a,c          23  b,e          37   c,d           32
    2  g,h          28  d,f          37   e,g           32
    3  a,b          28  c,d          39   a,c           34
    4  c,e          28  b,g          39   d,k           34
""".split('\n')[1:-1]]
df = pd.read_csv(StringIO(u'\n'.join(data)), sep='\s+')
print(df)

print(crazy_prod_sum_thing(df))

<强>结果:

  alfa  alfa_index beta  beta_index delta  delta_index
0  a,b          23  c,d          36   a,c           32
1  a,c          23  b,e          37   c,d           32
2  g,h          28  d,f          37   e,g           32
3  a,b          28  c,d          39   a,c           34
4  c,e          28  b,g          39   d,k           34

1          [aa,cc, bc,bd,ec,ed, ca,dd]
2          [ga,gc,ha,hc, db,ff, ec,gg]
3    [ag,bb, cd,cf,dd,df, ae,ag,ce,cg]
4                [ca,ee, bc,gg, da,kk]

注意:

这不会将结果编组回到问题中指示的数据框中,因为我不确定如何在不匹配时获取索引值。