生信log

生信log35|生信数据提取之数据'debug'-以处理基因映射

2023-05-07  本文已影响0人  小周的万用胶囊

记录一下这段时间对生信数据处理后遇到的问题和处理的方法。问题在于数据提取之后的数据存在错误。我把自己没检查导致数据错误和检查过但没发现的数据错误的情况拿出来处刑,顺便提醒一下其他小白同志。说起这个我发现生信领域对于处理数据这部分的内容有很多相关的教程,但却缺乏如何评估处理后的数据的教程和方法论。在此记录一下,说不定未来的某天还是写下的log帮助了自己。

1、错误的形式及处理方法

正确只有一种,但错误却能千奇百怪

常见的错误

  1. 缺乏理解:在处理数据之前,没有对数据本身和业务需求进行足够的了解和分析。

    • 这里需要与需求方进行不断的沟通,并且确认好提取的数据类型数据字段
  2. 忽略异常值:异常值是指与其他数据点明显不同的数据点

    • 数值类型的异常值可通过统计学的方法可视化的方法查找到。
  3. 忽略重复值

    • 重复值是指数据集中出现多次的相同数据,重复值出现的地方不仅仅是重复行,也可能是同一个各种出现多个值,但重复值的有些时候是具有意义的,所以删除前需要确认重复值是否具有意义。

    e.g1 数据有重复的行

    基因ID 基因名
    ENSG123 F-box/LRR-repeat
    ENSG123 F-box/LRR-repeat

    e.g2 数据同一行中有重复的值,如下表所示:

    基因ID 基因名
    ENSG123 F-box/LRR-repeat/F-box解决方法pandas实现方式(一般使用set的功能对重复值进行去重)
#表格去重
df.drop_duplicates(inplace=True)

#例子2去重,不同的数据用不同的代码,不要刻舟求剑!
unique_name = list(set(df['基因名'].str.split('/')))
df['基因名'] = unique_name
  1. 数据类型错误:使用错误的数据类型可能会导致数据计算错误。

    • 将文本数据视为数字数据;

    • 原本为int的数据变成了float的类型;

# pandas
import pandas as pd

# 读取数据前或构建dataframe前需要指定数据的类型
data = {'column1': [1, 2, 3], 'column2': ['4', '5', '6']}
df = pd.DataFrame(data, dtype={'column1': float, 'column2': int})

#转变dataframe的数据
df['column1'] = df['column1'].astype(float)
df['column2'] = df['column2'].astype(int)

#如果数据中有空值,需要预先填充空值
df['column1'] = df['column1'].fillna(0).astype(int)

#或者通过用apply和lambda函数跳过空值
df['column1'] = df['column1'].apply(lambda x: str(x) if x not np.nan else np.nan)
  1. 不考虑数据大小:在处理大型数据集时,需要考虑计算机的存储和内存限制。如果不考虑数据大小,可能会导致程序崩溃或运行缓慢。
  1. 忽略数据质量:传说中的garbage in garbage out!
  1. 空值
    • 有些时候数据库对数据的录入是有要求的,现实收集到的数据有用空格NoneNa、甚至是一些符号,因此处理控制的时候并不能根据已有的进行空值的填充,需要与需求方或者看自己需求填充空值。

    • python查找空值的方法,下面的两种方法会返回"True" or "False"

#查找空值
df.isnull()
df.isna()
#选择没有空值的子集
df[df.isnull() == False]
#选择某些列不为空值的操作
df[df['列名'].isna() == False]
df[df['列名'].isnull() == False]
import pandas as pd

#整表填充
df.fillna('填充的值', inplace=True) #这个是可以直接处理原表的数据

#只填充某一列的数据
df['column1'].fillna('填充的值', inplace=True)

#表中本来已经有表示空值的情况,避免pandas将空值转变成np.nan

df = pd.read_csv(data, na_values="指定的空值类型")

不常见但却经典的新手错误

gff示例数据
#gff基因数据如下
awk -v FS="\t" '$3~/gene/' demo.tsv|wc -l
>> 5
awk '$3~/gene/' demo.tsv|wc -l           
>> 4

2、如何科学地检查数据

  1. 抽样检查
import pandas

# 读取数据集
df = pd.read_csv('data.csv')

# 从数据集中抽取指定数量的数据,随机选取 10 个样本
sample_df = df.sample(n=10)

# 从数据集中按比例抽取数据,从数据集中随机选取 20% 的样本
sample_df = df.sample(frac=0.2)

# 对数据集进行加权抽样 
weights = [0.5, 0.3, 0.2] #定义样本权重

sample_df = df.sample(n=10, weights=weights, replace=True)
# 从文件中抽取100行的数
shuf -n 100 输入文件 > 输出文件
  1. 与源数据或者样品的示例数据进行比较
# 在 pandas 库中,DataFrame 和 Series 对象都提供了 equals() 方法,用于比较两个对象的相等性。
import pandas as pd
 
# 创建两个 DataFrame 对象
df1 = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
df2 = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
print(df1.equals(df2))

>>> True
#linux 方法
diff 文件1 文件2
# md5sum 校验
md5sum demo.tsv                                           
7fad8aac8cbfaabf7f6a0b2c70c50b1d  demo.tsv
md5sum demo2.tsv
7fad8aac8cbfaabf7f6a0b2c70c50b1d  demo2.tsv
  1. 请其他人(上级,有经验的同学、同事)帮忙检查

    为什么会说到这一点呢,新手会犯错很大一部分原因是因为对数据并不敏感,比如说基因可能在某些物种里面是不可能存在的但数据格式是正确的,这时候已经有可能是脚本出现错误了;类似的还有物种名字之间少了空格、sp后面少了'.',熟悉该领域的人一眼就能看出来。另外,旁观者清当局者迷,找其他人帮忙看看可能会发现不一样的错误。

3、总结

要明白一点数据清洗的并不是一蹴而就的,多番来回才是常态

评价一下python pandas

df1 = pd.DataFrame({'a': ['foo', 'bar'], 'b': [1, 2]})
>>> df1
      a  b
0   foo  1
1   bar  2
>>> df1.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2 entries, 0 to 1
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype 
---  ------  --------------  ----- 
 0   a       2 non-null      object
 1   b       2 non-null      int64 

df2 = pd.DataFrame({'a': ['foo', 'baz'], 'c': [3, 4]})
>>>df2
      a  c
0   foo  3
1   baz  4
>>> df2.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2 entries, 0 to 1
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype 
---  ------  --------------  ----- 
 0   a       2 non-null      object
 1   c       2 non-null      int64 
dtypes: int64(1), object(1)
memory usage: 160.0+ bytess

#合并两张表后查看数据类型
df3 = df1.merge(df2, how='left', on='a')
      a  b  c
0   foo  1  3.0
1   bar  2  NaN

>>> df3
     a  b    c
0  foo  1  3.0
1  bar  2  NaN   ##这里可以看到整数已经变成了浮点数

>>> df3.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 2 entries, 0 to 1
Data columns (total 3 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   a       2 non-null      object 
 1   b       2 non-null      int64  
 2   c       1 non-null      float64
dtypes: float64(1), int64(1), object(1)
memory usage: 64.0+ bytes

  1. 打开vim编辑器。
  2. 输入命令模式,按下冒号(:)键。
  3. 输入set list命令,按下回车键。
  4. 现在,你应该能够在文本中看到分割符的符号了。
vim set list cat -A | cat -t

后话:如果还有新的点会开另外一篇进行梳理和总结,有兴趣的看官点个关注~后面会有一篇专门总结和讨论数据处理效率的笔记。

Ps:seniors工程师都看不下去眼了,但新手总归会犯点错,多多总结,积极交流。


参考及推荐

生信log31|让Python代码高效(消除循环)的方法总结

pandas官方文档

上一篇 下一篇

猜你喜欢

热点阅读