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