首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从.dat文件中筛选列并从其他列返回给定值

从.dat文件中筛选列并从其他列返回给定值
EN

Stack Overflow用户
提问于 2017-06-04 15:19:08
回答 3查看 1.3K关注 0票数 1

我是Python新手,我一直在练习我创建的学生ID号码、年级、年龄、class_code、area_code等(150行)示例数据。我试图处理这些数据的方法不仅是由特定的列(按年级、年龄等)过滤,而且还要创建与该行(学生ID)不同的列的列表。我一直在忙着找出如何隔离我需要找出特定值的列,但后来却想不出如何创建我需要返回的值的列表。

下面是5行数据的示例:

代码语言:javascript
运行
复制
1/A/15/13/43214
2/I/15/21/58322
3/C/17/89/68470
4/I/18/6/57362
5/I/14/4/00000
6/A/16/23/34567

我需要一个第一列(学生ID)的列表,基于对第二列(年级).(最后是第三列、第四列等)的过滤。但是如果我看到第二列的样子,我想我可以找出其他的)也要注意:我没有在.dat文件中使用标题。

我想出了如何隔离/查看第二列。

代码语言:javascript
运行
复制
import numpy

data = numpy.genfromtxt('/testdata.dat', delimiter='/', dtype='unicode')

grades = data[:,1]
print (grades)

印刷:

代码语言:javascript
运行
复制
['A' 'I' 'C' 'I' 'I' 'A']

但是现在,我怎样才能把第一列对应于A,C,我分成不同的列表呢?

所以我想看到一个列表,还有A,C和I的第1列整数之间的逗号

代码语言:javascript
运行
复制
list from A = [1, 6]
list from C = [3]
list from I = [2, 4, 5]

再一次,如果我能看到它是如何用第二列来完成的,只有其中一个值(比如A),我想我可以想出如何对B,C,D,等等,以及其他列这样做。我只需要看一个如何应用语法的例子,然后再来看看其他的例子。

另外,我一直在使用numpy,但也读过有关熊猫、csv的文章,我认为这些库也可能是可能的。但就像我说的,.dat文件一直在使用numpy。我不知道其他库会不会更容易使用?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-06-04 16:08:18

熊猫解决方案:

代码语言:javascript
运行
复制
import pandas as pd

df = pd.read_csv('data.txt', header=None, sep='/')
dfs = {k:v for k,v in df.groupby(1)}

因此,我们有了一个DataFrames字典:

代码语言:javascript
运行
复制
In [59]: dfs.keys()
Out[59]: dict_keys(['I', 'C', 'A'])

In [60]: dfs['I']
Out[60]:
   0  1   2   3      4
1  2  I  15  21  58322
3  4  I  18   6  57362
4  5  I  14   4      0

In [61]: dfs['C']
Out[61]:
   0  1   2   3      4
2  3  C  17  89  68470

In [62]: dfs['A']
Out[62]:
   0  1   2   3      4
0  1  A  15  13  43214
5  6  A  16  23  34567

如果希望对第一列的列表进行分组:

代码语言:javascript
运行
复制
In [67]: dfs['I'].iloc[:, 0].tolist()
Out[67]: [2, 4, 5]

In [68]: dfs['C'].iloc[:, 0].tolist()
Out[68]: [3]

In [69]: dfs['A'].iloc[:, 0].tolist()
Out[69]: [1, 6]
票数 1
EN

Stack Overflow用户

发布于 2017-06-04 16:19:55

实际上,对于这样简单的任务,您不需要任何额外的模块。纯Python解决方案是逐行读取文件,使用str.split()对它们进行“解析”将给出您的列表,然后您几乎可以对任何参数进行筛选。类似于:

代码语言:javascript
运行
复制
students = {}  # store for our students by grade
with open("testdata.dat", "r") as f:  # open the file
    for line in f:  # read the file line by line
        row = line.strip().split("/")  # split the line into individual columns
        # you can now directly filter your row, or you can store the row in a list for later
        # let's split them by grade:
        grade = row[1]  # second column of our row is the grade
        # create/append the sublist in our `students` dict keyed by the grade
        students[grade] = students.get(grade, []) + [row]
# now your students dict contains all students split by grade, e.g.:
a_students = students["A"]
# [['1', 'A', '15', '13', '43214'], ['6', 'A', '16', '23', '34567']]

# if you want only to collect the A-grade student IDs, you can get a list of them as:
student_ids = [entry[0] for entry in students["A"]]
# ['1', '6']

但是,让我们返回几个步骤-如果您想要一个更通用的解决方案,您只需存储您的列表,然后创建一个函数来通过传递的参数过滤它,因此:

代码语言:javascript
运行
复制
# define a filter function
# filters should contain a list of filters whereas a filter would be defined as:
# [position, [values]]
# and you can define as many as you want
def filter_sublists(source, filters=None):
    result = []  # store for our result
    filters = filters or []  # in case no filter is returned
    for element in source:  # go through every element of our source data
        try:
            if all(element[f[0]] in f[1] for f in filters):  # check if all our filters match
                result.append(element)  # add the element
        except IndexError:  # invalid filter position or data position, ignore
            pass
    return result  # return the result

# now we can use it to filter our data, first lets load our data:

with open("testdata.dat", "r") as f:  # open the file
    students = [line.strip().split("/") for line in f]  # store all our students as a list

# now we have all the data in the `students` list and we can filter it by any element
a_students = filter_sublists(students, [[1, ["A"]]])
# [['1', 'A', '15', '13', '43214'], ['6', 'A', '16', '23', '34567']]

# or again, if you just need the IDs:
a_student_ids = [entry[0] for entry in filter_sublists(students, [[1, ["A"]]])]
# ['1', '6']

# but you can filter by any parameter, for example:
age_15_students = filter_sublists(students, [[2, ["15"]]])
# [['1', 'A', '15', '13', '43214'], ['2', 'I', '15', '21', '58322']]

# or you can get all I-grade students aged 14 or 15:
i_students = filter_sublists(students, [[1, ["I"]], [2, ["14", "15"]]])
# [['2', 'I', '15', '21', '58322'], ['5', 'I', '14', '4', '00000']]
票数 2
EN

Stack Overflow用户

发布于 2017-06-04 15:45:08

您可以遍历列表并创建一个布尔值来选择与特定级别匹配的数组。这可能需要一些改进。

代码语言:javascript
运行
复制
import numpy as np

grades = np.genfromtxt('data.txt', delimiter='/', skip_header=0, dtype='unicode')


res = {}
for grade in set(grades[:, 1].tolist()):
    res[grade] = grades[grades[:, 1]==grade][:,0].tolist()

print res
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44355619

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档