Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用python排序csv文件_Python_Sorting_Csv - Fatal编程技术网

用python排序csv文件

用python排序csv文件,python,sorting,csv,Python,Sorting,Csv,我正在尝试按列对csv文件进行排序。该文件有许多列,如下所示: 汤姆,01AA01234.56334 艾丽斯,01AS01546.093434.3 山姆,01NA014574.3,65.45 乔伊,01BA012897.03455 Pam,01MA01434.034454 约翰,01AA02343,24 艾丽斯,01AS02454454.54 汤姆,02BA01343454.2 它持续大约20列和250行 我希望它按第二列排序,并按字母顺序排列第二部分中的AA,AS,BA,第三部分按数字排序'0

我正在尝试按列对csv文件进行排序。该文件有许多列,如下所示:

汤姆,01AA01234.56334

艾丽斯,01AS01546.093434.3

山姆,01NA014574.3,65.45

乔伊,01BA012897.03455

Pam,01MA01434.034454

约翰,01AA02343,24

艾丽斯,01AS02454454.54

汤姆,02BA01343454.2

它持续大约20列和250行

我希望它按第二列排序,并按字母顺序排列第二部分中的
AA
AS
BA
,第三部分按数字排序
'01',02',03',
,第一部分按数字排序
'01',02',03'
。然后根据此排序创建一个新的csv文件。它们通常不只是6个字符长,其他的看起来像
'02BAA',01MAA',02NAA'
等等

因此,在第2列中,最终的结果应该是这样的

01AA01
01AS01
01BA01
01MA01
01NA01
01AA02
01AS02
02BA01

我对编码还不熟悉,不太清楚如何进行编码。提前感谢您。

Python的
排序
函数中ASCII字符串的默认排序顺序是(或“ASCIIbetical”):

与列表值为整数时的整数幅值相比:

>>> sorted(map(int, li))
[1, 11, 20, 100]
也就是说,字符串中数字对人眼的大小不同于相同字符串对计算机眼睛的大小。(在中更广泛地描述)

要解决这个问题,我们需要将字母与数字分开,并将数字转换为整数(或浮点数)

最简单的方法是使用一个正则表达式,它捕获所有数字,然后转换为整数,然后再转换为所有字母

这将分类到您的目标:

li1='''\
01AA01
01AS01
01NA01
01BA01
01MA01
01AA02
01AS02
02BA01'''.splitlines()

tgt='''\
01AA01
01AS01
01BA01
01MA01
01NA01
01AA02
01AS02
02BA01'''.splitlines()


import re

def kf(s):
    nums=map(int, re.findall(r'(\d+)', s)) 
    lets=re.findall(r'([a-zA-Z]+)', s)
    return nums+lets   

print tgt==sorted(li1, key=kf)
# True
或者,一行:

>>> tgt==sorted(li1, key=lambda s: map(int, re.findall(r'(\d+)', s))+re.findall(r'(\D+)', s))
True

根据评论进行编辑

问题案文指出:

我希望它在第一部分01,02,03中以数字顺序排列。。。 然后在第二部分按字母顺序排列AA,AS,BA,和 第三部分再次进行数值计算

然而,这个例子表明情况并非如此

我们可以根据(int,letters,int)的模式进行分类,并使用split:

>>> [re.split(r'(\D+)', e) for e in li1]
[['01', 'AA', '01'], ['01', 'AS', '01'], ['01', 'NA', '01'], ['01', 'BA', '01'], ['01', 'MA', '01'], ['01', 'AA', '02'], ['01', 'AS', '02'], ['02', 'BA', '01']]
>>> sorted(li1, key=lambda s: [int(e) if e.isdigit() else e for e in re.split(r'(\D+)', s)])
['01AA01', '01AA02', '01AS01', '01AS02', '01BA01', '01MA01', '01NA01', '02BA01']
#             ^^        ^^        etc '01AA02', before '01AS01' in the example
通过检查,发布示例的模式是
(int,int,letters)
,可以在这里看到:

>>> [map(int, re.findall(r'(\d+)', s))+re.findall(r'(\D+)', s) for s in li1]
[[1, 1, 'AA'], [1, 1, 'AS'], [1, 1, 'NA'], [1, 1, 'BA'], [1, 1, 'MA'], [1, 2, 'AA'], [1, 2, 'AS'], [2, 1, 'BA']]
如果文本正确,请使用我的拆分形式排序;如果示例正确,请使用
nums+lets
表单

sorted()
和列表的
.sort()
方法采用可选参数

其中:

指定一个参数的函数,用于提取 每个列表元素的比较键:key=str.lower

换句话说,给定给键参数的函数(您将编写)解析并返回给定对象的可排序值

因此,根据您的输入,
“01AS01”
,您希望将其分解为易于排序的部分

正如您提到的,您希望结果按(int,str,int)排序。由于
sorted()
.sort()
会自动按数字排序(对于整数)和字母排序(对于字符串),因此,对于键函数,您只需将值分解,
“01AS01”
分为
[1,“AS”,1]
排序()
//code>。sort()将处理其余部分

这是一个与dawg类似的示例,但没有使用
map()
re


假设这是一个csv文件,每行是一行,每列用逗号标记。因为没有给我们一个你的csv的exmaple,我编了一个有两列的,你的数据在第[1]列

>>> print open('mycsv.csv').read()
fred, 01AA01
brenda, 01BA01
bob, 01AA02
alice, 01NA01
jane, 01AS01
blane, 02BA01
larry, 01MA01
mary, 01AS02
这些都可以通过csv模块读取到列表中。最后是一个行列表,其中列是另一个列表

>>> import csv
>>> table=[row for row in csv.reader(open('mycsv.csv')) if row]
>>> print table
[['fred', ' 01AA01'], ['brenda', ' 01BA01'], ['bob', ' 01AA02'], ['alice', ' 01NA01'], ['jane', ' 01AS01'], ['blane', ' 02BA01'], ['larry', ' 01MA01'], ['mary', ' 01AS02']]
您可以对该列表进行排序。默认情况下,排序从第一个键开始,如果第一个键相同,则从第二个键开始,以此类推。因此,它将按“fred”等进行排序。。。但您可以选择不同的排序键。Python对每个列表项调用键函数,以便您可以将其转换为所需的内容。转换可以是简单的,如使小写,也可以是复杂的

对排序键使用lambdas是很常见的,但这可能有点高级,所以这里有一个函数,它只获取您想要的键

>>> def item_1(row):
...     return row[1]
... 
>>> print table
[['fred', ' 01AA01'], ['bob', ' 01AA02'], ['jane', ' 01AS01'], ['mary', ' 01AS02'], ['brenda', ' 01BA01'], ['larry', ' 01MA01'], ['alice', ' 01NA01'], ['blane', ' 02BA01']]
>>> 

请注意,如果所有列值都是这样的,那么排序将保留您想要的顺序。例如,对该列进行排序会自动满足您的所有条件。所以您可以将问题简化为按列排序CSV,因为这里不需要特殊的排序条件。@Tommy-我不明白。。。你是说既然样本已经按照OP想要的方式排序,那么它们都必须按照OP想要的方式排序吗?@Tammy,你用什么工具来管理csv,csv模块?在您要排序的时候它是否在python列表中?更多问题!字段大小是否始终相同(2位数字、2个字母、2位数字)?这似乎是按第一、第三和第二部分排序的。例如,“01AA01”将按键(1,1,“AA”)排序。这就是示例的排序方式。因此
01AS01
01AA02
您的右边之前进行排序!我偏离了文本,这似乎意味着按第一、第二和第三组进行排序。
>>> import csv
>>> table=[row for row in csv.reader(open('mycsv.csv')) if row]
>>> print table
[['fred', ' 01AA01'], ['brenda', ' 01BA01'], ['bob', ' 01AA02'], ['alice', ' 01NA01'], ['jane', ' 01AS01'], ['blane', ' 02BA01'], ['larry', ' 01MA01'], ['mary', ' 01AS02']]
>>> def item_1(row):
...     return row[1]
... 
>>> print table
[['fred', ' 01AA01'], ['bob', ' 01AA02'], ['jane', ' 01AS01'], ['mary', ' 01AS02'], ['brenda', ' 01BA01'], ['larry', ' 01MA01'], ['alice', ' 01NA01'], ['blane', ' 02BA01']]
>>>