首页 > 解决方案 > 在 python 中识别 CSV 列/行中的模式

问题描述

大家好,提前感谢您的帮助。

我试图解决的问题如下:

我在一个 CSV 文件中有两列:A 列和 B 列。

在 A 列和 B 列下的每一行中,我的数据中需要存在某些模式。

例如,如果 A 列的第 1 行有一个“1”,则 B 列的第 1 行必须有一个“5”与之相邻。

如果 A 列的第二行有“1”,而 BI 列的第 2 行与之相邻的“2”需要将其标记并打印为“不遵循模式”

规则如下:

这是我在代码上的位置,我似乎无法找出进行此数据检查的方法。

import numpy as np
import pandas as pd
import os  # filepaths
import glob
import getpass  # Login information


unane = getpass.getuser()

# Paths:
path2proj = os.path.join('C:', os.sep, 'Users', unane, 'Documents', 'Home','Expts','TSP', '')
path2data = os.path.join(path2proj,'Data','')
path2asys = os.path.join(path2proj,'Analysis', '')
path2figs = os.path.join(path2asys, 'figures', '')
path2hddm = os.path.join(path2asys, 'modeling', '')

df = pd.read_csv(path2data + '001_2012_Dec_19_0932_PST_train.csv')

os.chdir(path2data)

# extension = 'csv'
# all_filenames = [i for i in glob.glob('*.{}'.format(extension))]

all_filenames = glob.glob("*.csv")
combined_csv = pd.concat([pd.read_csv(f) for f in all_filenames]) 
combined_csv.to_csv("combined_csv.csv",index=False, encoding='utf-8-sig')

df = pd.read_csv(path2data + 'combined_csv.csv')
df['left_stim_number'].equals(df['right_stim_number'])
df = pd.read_csv(path2data + 'combined_csv.csv')
df1 = pd.DataFrame(df, columns=['left_stim_number'])
df2 = pd.DataFrame(df, columns=['right_stim_number'])
df1['match'] = np.where(df1['left_stim_number']== df2['right_stim_number'], True, False)

# Checking to see if there are any errors as all should add up to 7
df1['add'] = np.where(df1['left_stim_number']== df2['right_stim_number'], 0, df1['left_stim_number'] + df2['right_stim_number'])

# def see_correct(df):
#    if df1['add'] == ['7']:
#        return 1
#    else: 
#        return 0
    
# df1.tail(10)

combined_csv.isna().sum()
combined_csv.dropna()

df.loc[df['left_stim_number'] != df['right_stim_number'],:]






---

Example of CSV data

A(left_stim_number)        Column B (Right_stim_number)
1                 5

1                 5

3                 6

1                 5

3                 6

2                 4

2                 4

2                 4

1                 5

标签: pythonpandasdataframe

解决方案


由于我们没有示例,我将编写一个示例 - 一个带有两列整数的 pandas DataFrame。

import numpy as np
import pandas as pd
np.random.seed(2)
df = pd.DataFrame({'colA':np.random.randint(0,10,100),
                   'colB':np.random.randint(0,10,100)})

>>> df.head()
   colA  colB
0     8     7
1     8     1
2     6     9
3     2     2
4     8     1

可能有更简洁的方法可以做到这一点,这很清楚正在发生什么。这使用了大量的布尔索引

您的规则排除了任何colA不是 1、2 或 3 的行colB。也排除了不是 4、5 或 6 的行。您可以为所有排除的行制作掩码。

mask = ~df.colA.isin([1,2,3]) | ~df.colB.isin([4,5,6])

>>> df[mask].head()
   colA  colB
0     8     7
1     8     1
2     6     9
3     2     2
4     8     1
>>>

您可以使用掩码将“未遵循模式”分配给所有这些行的新列。

df.loc[mask,'colC'] = 'pattern not followed'

>>> df.head()
   colA  colB                  colC
0     8     7  pattern not followed
1     8     1  pattern not followed
2     6     9  pattern not followed
3     2     2  pattern not followed
4     8     1  pattern not followed

您还可以使用掩码查找可能符合您的条件的所有行。注意这些colCNaN

>>> df[~mask]
    colA  colB colC
13     3     5  NaN
35     2     6  NaN
39     1     5  NaN
61     2     5  NaN
62     1     5  NaN
65     1     6  NaN
69     1     5  NaN
70     2     4  NaN
77     3     5  NaN
92     1     6  NaN
98     2     5  NaN
>>>

colC满足条件的行设置为 True(?)。

df.loc[(df.colA == 1) & (df.colB == 5),'colC'] = True
df.loc[(df.colA == 3) & (df.colB == 6),'colC'] = True
df.loc[(df.colA == 2) & (df.colB == 4),'colC'] = True

这留下了一些异常值。

>>> df.loc[df.colC.isna()]
    colA  colB colC
13     3     5  NaN
35     2     6  NaN
61     2     5  NaN
65     1     6  NaN
77     3     5  NaN
92     1     6  NaN
98     2     5  NaN

哪个可以修复。

df.loc[df.colC.isna(),'colC'] = 'pattern not followed'

看完之后,需要最后四个操作。

df.loc[(df.colA == 1) & (df.colB == 5),'colC'] = True
df.loc[(df.colA == 3) & (df.colB == 6),'colC'] = True
df.loc[(df.colA == 2) & (df.colB == 4),'colC'] = True

df.loc[df.colC.isna(),'colC'] = 'pattern not followed'


>>> df.loc[df.colC == True]
    colA  colB  colC
39     1     5  True
62     1     5  True
69     1     5  True
70     2     4  True
>>>

如果 csv 文件中的文本如下所示 -

4,9
8,3
4,6
2,4
7,5
1,3
 .
 .
 .

数据框可以用 -

df = pd.read_csv('data.csv',names=['colA','colB'])

推荐阅读