[英]Sort a file by first (or second, or else) column in python
這似乎是一個非常基本的問題,但我是python的新手,在花了很長時間試圖找到自己的解決方案后,我認為是時候問一些更高級的人了!
所以,我有一個文件(樣本):
ENSMUSG00000098737 95734911 95734973 3 miRNA
ENSMUSG00000077677 101186764 101186867 4 snRNA
ENSMUSG00000092727 68990574 68990678 11 miRNA
ENSMUSG00000088009 83405631 83405764 14 snoRNA
ENSMUSG00000028255 145003817 145032776 3 protein_coding
ENSMUSG00000028255 145003817 145032776 3 processed_transcript
ENSMUSG00000028255 145003817 145032776 3 processed_transcript
ENSMUSG00000098481 38086202 38086317 13 miRNA
ENSMUSG00000097075 126971720 126976098 7 lincRNA
ENSMUSG00000097075 126971720 126976098 7 lincRNA
我需要編寫一個包含所有相同信息的新文件,但按第一列排序。
到目前為止我使用的是:
lines = open(my_file, 'r').readlines()
output = open("intermediate_alphabetical_order.txt", 'w')
for line in sorted(lines, key=itemgetter(0)):
output.write(line)
output.close()
它不會返回任何錯誤,但只是將輸出文件寫為輸入文件。
我知道這肯定是一個非常基本的錯誤,但如果你們中的一些人能夠告訴我我做錯了什么,那就太棒了!
非常感謝!
我打開文件的方式有問題,所以有關已經打開的數組的答案並沒有真正幫助。
如果輸入文件是以制表符分隔的,則還可以使用csv模塊。
import csv
from operator import itemgetter
reader = csv.reader(open("t.txt"), delimiter="\t")
for line in sorted(reader, key=itemgetter(0)):
print(line)
按第一欄排序。
更改號碼
key=itemgetter(0)
用於按不同的列排序。
你遇到的問題是你沒有把每一行都變成一個列表。 當您讀入文件時,您只是將整行作為字符串。 然后按照每行的第一個字符進行排序,這在輸入中始終是相同的字符'E'
。
要按第一列排序,您需要關閉第一個塊,然后只讀取該部分。 所以你的關鍵應該是:
for line in sorted(lines, key=lambda line: line.split()[0]):
split
會將您的行轉換為列表,然后從該列表中獲取第一列。
與SuperBiasedMan相同的想法,但我更喜歡這種方法:如果你想要另一種排序方式(例如:如果第一列匹配,按第二列排序,然后是第三列等),則更容易實現
with open(my_file) as f:
lines = [line.split(' ') for line in f]
output = open("result.txt", 'w')
for line in sorted(lines):
output.write(' '.join(line), key=itemgetter(0))
output.close()
您可以編寫一個函數,使用csv.reader
解析文件,使用文件名,分隔符和列進行排序:
from operator import itemgetter
import csv
def sort_by(fle,col,delim):
with open(fle) as f:
r = csv.reader(f, delim=delim)
for row in sorted(r, key=itemgetter(col)):
yield row
for row in sort_by("your_file",2, "\t"):
print(row)
您可以使用pandas快速完成此操作,如下所示,數據文件的設置與您顯示的完全相同 (即,使用可變空格作為分隔符):
import pandas as pd
df = pd.read_csv('csvdata.csv', sep=' ', skipinitialspace=True, header=None)
df.sort(columns=[0], inplace=True)
df.to_csv('sorted_csvdata.csv', header=None, index=None)
只是為了檢查結果:
with open('sorted_csvdata.csv', 'r') as f:
print(f.read())
ENSMUSG00000028255,145003817,145032776,3,protein_coding
ENSMUSG00000028255,145003817,145032776,3,processed_transcript
ENSMUSG00000028255,145003817,145032776,3,processed_transcript
ENSMUSG00000077677,101186764,101186867,4,snRNA
ENSMUSG00000088009,83405631,83405764,14,snoRNA
ENSMUSG00000092727,68990574,68990678,11,miRNA
ENSMUSG00000097075,126971720,126976098,7,lincRNA
ENSMUSG00000097075,126971720,126976098,7,lincRNA
ENSMUSG00000098481,38086202,38086317,13,miRNA
ENSMUSG00000098737,95734911,95734973,3,miRNA
您可以通過在colmuns = [...]關鍵字參數中向列表中添加其他列來執行多列排序。
這是另一種選擇。 類似於上面的一些想法。 基本上,mysort是一個函數,它將為你做基於的自定義排序
def mysort(line):
return line.split()[0]
with open("records.txt", "r") as f:
text = f.readlines()
for line in sorted(text, key=mysort):
print line
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.