如何使用python将数据帧中行的每个值与之前行中的每个值进行比较?

2024-10-03 06:27:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个dataframe,看起来像这样(列和行的数量可能不同):

                0         1         2
2015-01-02    ISIN1     ISIN2     ISIN3
2015-05-04    ISIN4     ISIN2     ISIN5
2015-09-01    ISIN4     ISIN5     ISIN6
2016-01-04    ISIN7     ISIN8     ISIN2
2016-05-02    ISIN9     ISIN7     ISIN10
2016-09-01    ISIN11    ISIN12    ISIN13
2017-01-02    ISIN11    ISIN12    ISIN14
2017-05-02    ISIN12    ISIN11    ISIN15
2017-09-01    ISIN12    ISIN16    ISIN17
2018-01-02    ISIN16    ISIN11    ISIN18
2018-05-02    ISIN4     ISIN8     ISIN7
2018-09-03    ISIN12    ISIN7     ISIN19
2019-01-02    ISIN20    ISIN21    ISIN22
2019-05-02    ISIN13    ISIN7     ISIN8
2019-09-02    ISIN23    ISIN24    ISIN15
2020-01-02    ISIN25    ISIN23    ISIN24
2020-05-04    ISIN24    ISIN26    ISIN4

我现在的任务是将每一行的每个值与前面的行的每个值进行比较。我想知道该值是否在前一行中。我想得到两个数据帧作为结果

  1. 保留行中不在前的值:

                    0         1         2
    2015-01-02    ISIN1     ISIN2     ISIN3
    2015-05-04    ISIN4     ISIN5
    2015-09-01    ISIN6
    2016-01-04    ISIN7     ISIN8     ISIN2
    2016-05-02    ISIN9     ISIN10
    2016-09-01    ISIN11    ISIN12    ISIN13
    2017-01-02    ISIN14
    2017-05-02    ISIN15
    2017-09-01    ISIN16    ISIN17
    2018-01-02    ISIN11    ISIN18
    2018-05-02    ISIN4     ISIN8     ISIN7
    2018-09-03    ISIN12    ISIN19
    2019-01-02    ISIN20    ISIN21    ISIN22
    2019-05-02    ISIN13    ISIN7     ISIN8
    2019-09-02    ISIN23    ISIN24    ISIN15
    2020-01-02    ISIN25    
    2020-05-04    ISIN26    ISIN4
    
  2. 将行中的值保留在以下值之前:

                    0         1         2
    2015-01-02    
    2015-05-04    ISIN2
    2015-09-01    ISIN4     ISIN5
    2016-01-04    
    2016-05-02    ISIN7
    2016-09-01    
    2017-01-02    ISIN11    ISIN12    
    2017-05-02    ISIN12    ISIN11    
    2017-09-01    ISIN12    
    2018-01-02    ISIN16    
    2018-05-02    
    2018-09-03    ISIN7
    2019-01-02    
    2019-05-02    
    2019-09-02    
    2020-01-02    ISIN23    ISIN24
    2020-05-04    ISIN24
    

到目前为止,我已经探索了:

for i in range(len(df)):
    print(np.isin(df.values[i, :], df.shift().values[i, :]))

创建以下内容:

[False False False]
[False  True False]
[ True  True False]
[False False False]
[False  True False]
[False False False]
[ True  True False]
[ True  True False]
[ True False False]
[ True False False]
[False False False]
[False  True False]
[False False False]
[False False False]
[False False False]
[False  True  True]
[ True False False]

通过将这些值附加到列表中,我将能够创建一个新的数据帧。但我认为一定有更好的办法

有没有人知道如何在不遍历数据帧的情况下实现这一点

多谢各位

致以最良好的祝愿, 内皮


Tags: 数据falsetrueisin2isin12isin24isin13isin23
3条回答

嘿,也许你在找这样的东西:

data = {'first': ['ok', 'none', 'ok', 'ok', 'ok', 'ok', 'ok', 'ok', 'none', 'ok'],
        'second': [1, 3, 4, 7, 8, 2, 4, 9, 6, 9]}
df = pd.DataFrame(data, columns = ['first', 'second'])

df_results = df.eq(df.shift())
df_results.where(df_results != False, df)

希望能有所帮助

我又挖了一个深洞。我的解决方案是:

import pandas as pd
import numpy as np

row_0 = np.array(['ISIN1', 'ISIN4', 'ISIN4', 'ISIN7', 'ISIN9', 'ISIN11', 'ISIN11', 'ISIN12', 'ISIN12', 'ISIN16', 'ISIN4', 'ISIN12', 'ISIN20', 'ISIN13', 'ISIN23', 'ISIN25', 'ISIN24'])
row_1 = np.array(['ISIN2', 'ISIN2', 'ISIN5', 'ISIN8', 'ISIN7', 'ISIN12', 'ISIN12', 'ISIN11', 'ISIN16', 'ISIN11', 'ISIN8', 'ISIN7', 'ISIN21', 'ISIN7', 'ISIN24', 'ISIN23', 'ISIN26'])
row_2 = np.array(['ISIN3', 'ISIN5', 'ISIN6', 'ISIN2', 'ISIN10', 'ISIN13', 'ISIN14', 'ISIN15', 'ISIN17', 'ISIN18', 'ISIN7', 'ISIN19', 'ISIN22', 'ISIN8', 'ISIN15', 'ISIN24', 'ISIN4'])

data = {0:row_0, 1:row_1, 2:row_2}

df = pd.DataFrame(data)
print(df)
df_in_row_before = df[pd.DataFrame(np.array([np.isin(df.values[i, :], df.shift().values[i, :]) for i in range(len(df))]))]

print(df_in_row_before)
df_not_in_row_before = df[pd.DataFrame(np.array([np.isin(df.values[i, :], df.shift().values[i, :], invert=True) for i in range(len(df))]))]
print(df_not_in_row_before)

这正是我所需要的。但如果有人有更好的解决方案,我很乐意看看

以下是用NaN替换重复值的方法:

df = pd.DataFrame(dict(a=[1,1,2,2,4], b=[0,5,6,6,8]), index=np.arange(5)+100)
mask = np.full_like(df, False, dtype=bool)
mask[1:] =  df.iloc[1:].reset_index(drop=True) == df.iloc[:-1].reset_index(drop=True)
df[mask] = None

需要reset_index操作,否则,pandas将尝试对匹配的行索引执行==比较

原始数据帧:

     a  b
100  1  0
101  1  5
102  2  6
103  2  6
104  4  8

之后:

       a    b
100  1.0  0.0
101  NaN  5.0
102  2.0  6.0
103  NaN  NaN
104  4.0  8.0

相反,你需要这样做

mask = np.logical_not(mask)

相关问题 更多 >