0

我有看起来像这样的数据,比如说制表符分隔的格式:

Sample  Dog Cat Tarsier
A47 1   7   2
A48 3   3   4
A51 2   1   8
A53 0   0   0
A54 1   7   2
A57 0   0   10

虽然这里可能不清楚,但样本名称在第一列,值对应于 Dog、cat 或 Tarsier。我想保留,比如说每个样本的 90% 的数据,并在 PYTHON 中删除其余的数据。例如,对于示例 A47,我想检索如下内容:

      Cat   Tarsier
A47    7       2

这对我来说很难,因为每个样本我需要 3 条信息:样本名称、动物和数量。有什么想法吗?提前致谢

根据下面的评论,第二行可能包括所有数字,但排除可能存在的所有其他数字(未显示)。这是因为在这种情况下,如果没有第二个 3,则只有不到 90% 的数据,这可能比拥有 >90% 的数据更糟糕。如何做到这一点超出了我的 PYTHON 编程技能。

4

3 回答 3

0

假设您使用的是 Python 3(它也可能在 Py2 中工作,但我不知道),只需将其视为由制表符而不是逗号分隔的 CSV——

import csv

def getvals(file):
    """
        gets the val's from a file of whitespace separated values, and 
        turns them into easy to use Python var's
    """
    samples = csv.reader(open(file))
    s = []
    n = 0
    for row in samples:
        r = [row[0].split()]
        s += r
        n+=1
    return s

该函数将返回一个如下所示的集合——

[
 ['Sample', 'Dog', 'Cat', 'Tarsier'], 
 ['A47', '1', '7', '2'], 
 ['A48', '3', '3', '4'], 
 ['A51', '2', '1', '8'], 
 ['A53', '0', '0', '0'], 
 ['A54', '1', '7', '2'], 
 ['A57', '0', '0', '10']
]

从那里,确定要丢弃哪个值只是一些数学问题。当然,您也可以在 for 循环中进行数学运算并返回您想要的值。我只是想返回许多其他函数可以使用的值集,所以我就这样做了。

于 2012-09-14T00:21:04.620 回答
0

我强烈建议您考虑NumPy

使用 NumPy,您可以定义所谓的结构化数组,即每行由您可以直接命名和访问的不同字段组成的数组。

假设您的数据存储在制表符分隔的文件data.dat中,使用您描述的格式,您会这样做

>>> data = np.genfromtxt('data.txt', delimiter="\t", names=True, dtype=None)

np.genfromtxt函数从 读取您的数据'data.txt',沿 分割每一行delimiter,使用第一行获取字段的名称 ( names=True),并猜测每个字段的数据类型 ( data=None)。以你的例子,我得到

data = array([('A47', 1, 7, 2), ('A48', 3, 3, 4), ('A51', 2, 1, 8),
       ('A53', 0, 0, 0), ('A54', 1, 7, 2), ('A57', 0, 0, 10)], 
      dtype=[('Sample', '|S3'), ('Dog', '<i8'), ('Cat', '<i8'), ('Tarsier', '<i8')])

从这里,我们可以选择字段组合

>>> data[["Cat","Tarsier"]]
array([(7, 2), (3, 4), (1, 8), (0, 0), (7, 2), (0, 10)], 
  dtype=[('Cat', '<i8'), ('Tarsier', '<i8')])

或只有几行:

>>> data[[0,2]]
array([('A47', 1, 7, 2), ('A51', 2, 1, 8)], 
     dtype=[('Sample', '|S3'), ('Dog', '<i8'), ('Cat', '<i8'), ('Tarsier', '<i8')])

对某个字段进行一些统计:

>>> data["Dog"].mean()
1.1666667

简而言之,您可以按照自己的方式过滤数据。

于 2012-09-14T09:05:39.503 回答
0

如果我是对的,您删除了“狗”,因为它<=动物总数的 10%。让我们创建一个结构

struct row{
    char *name;
    int animal[3]; //id 0 is dog, 1 is cat and 2 is tarsier
}

然后每次将读取的数据放入此结构时,您可以简单地将每个字段设置为 0 <=10%:

int i;
float sum=0; //we need float to force the result to be float
for (i=0;i<3;i++){
    sum += row.animal[i]; //count the total row population
}
for (i=0;i<3;i++){ //for every animal
    if (row.animal[i]/sum <= 0.1){ //if this animal is equal or less than 10% of the row population
        row.animal[i]=0; //set his population to 0
    }
}

如您所见,由于具有此代码的动物数组,您可以拥有任意(但固定)数量的动物。

于 2012-09-13T23:32:00.780 回答