如何计算各列中的变化值-Pandas Dataframe

时间:2018-08-07 18:58:00

标签: python pandas

随着时间的推移,我试图查看特定功能以获取不同的唯一ID,并将其存储在Pandas的数据框中。

下面是一个示例,其中包含要复制的代码:

from IPython.core.display import display, HTML
display(HTML('<h1>Hello, world!</h1>'))
iplot(fig)

我想计算一个特定ID的t *值变化的次数。示例:

John值从A开始并移至B(一个变化),然后保持在B(无变化),然后在t4(第二个变化)移至A,所以总共有两个变化。

预期输出如下:

d = {'id': ['adam', 'john'],'t1': ['A', 'A'], 't2': ['A', 'B'], 't3': ['A', 'B'], 't4': ['B', 'A']}
df = pd.DataFrame(data=d)
df

     id t1 t2 t3 t4
0  adam  A  A  A  B
1  john  A  B  B  A

4 个答案:

答案 0 :(得分:4)

s = df[df.columns[1:]]
df.assign(total_change=s.ne(s.shift(axis=1).bfill(1)).sum(1))

输出:

     id t1 t2 t3 t4  total_change
0  adam  A  A  A  B             1
1  john  A  B  B  A             2

这将比其numpy慢:

df = pd.concat([df]*10000)
s = df[df.columns[1:]]
v = df.filter(regex='^t\d+').values

%%timeit
df.assign(total_change=s.ne(s.shift(axis=1).bfill(1)).sum(1))    
21.2 ms ± 256 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

%%timeit
df.assign(total_change=(v[:, 1:] != v[:, :-1]).sum(1))
1.9 ms ± 8.53 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

答案 1 :(得分:4)

相同的想法,但使用Numpy

v = df.filter(regex='^t\d+').values
df.assign(total_change=(v[:, 1:] != v[:, :-1]).sum(1))

     id t1 t2 t3 t4  total_change
0  adam  A  A  A  B             1
1  john  A  B  B  A             2

答案 2 :(得分:3)

您可以使用:

df.merge((df.set_index('id').shift(1,axis=1).bfill(1) != df.set_index('id')).sum(1)
            .rename('total_change')
            .to_frame(), 
          left_on='id', 
          right_index=True)

输出:

     id t1 t2 t3 t4  total_change
0  adam  A  A  A  B             1
1  john  A  B  B  A             2

答案 3 :(得分:1)

您可以过滤列并遍历行中的所有值并检查更改:

columns_needed =  [col for col in df.columns.values if col.startswith('t')]
df['toatal_change'] = df[columns_needed].apply(lambda row: sum([1 for val, val2 
                                          in zip(row, row[1:]) if val != val2]),axis=1)

结果为:

     id t1 t2 t3 t4  toatal_change
0  adam  A  A  A  B              1
1  john  A  B  B  A              2

lambda中的apply表达式等效于:

def check_chage(row):
    is_eq_next_val = [1 for val, val2 in zip(row, row[1:]) if val != val2]
    return sum(is_eq_next_val)