как сделать уникальные данные из строк

У меня есть такие данные. строки разделяются запятой.

"India1,India2,myIndia     "
"Where,Here,Here   "
"Here,Where,India,uyete"
"AFD,TTT"

То, что я пытаюсь сделать, это поместить их все в один столбец (один под другим). Таким образом, это станет таким

India1
India2
myIndia
Where
Here
Here
Here
Where
India
uyete
AFD
TTT

Затем я сохраняю уникальные, которые ведут к этому

India1
India2
myIndia
Where
Here
India
uyete
AFD
TTT

Итак, у меня есть первые данные в формате .txt, и я попытался использовать для этого numpy.

это мой код

#!/usr/bin/python
import numpy as np

# give a name to my data 
file_name = 'path to my data/test.txt'
# set my output 
with open ( 'output.txt' , 'w' ) as out:
    # read all the lines
    for n , line in enumerate ( open ( file_name ).readlines ( ) ):
        # split each stirg from another one by a comma
        item1 = file_name.split ( ',' )
    myList = ','.join ( map ( str , item1 ) )
    item2 = np.unique ( myList , return_inverse=True )
    # save the data into out
    out.write ( item2 )

Я получал TypeError: expected a character buffer object

Я искал его и нашел несколько сообщений типа TypeError: ожидается объект символьного буфера - при попытке сохранить целое число в текстовый файл

и если я добавил out.seek ( 0 ), я все равно получил ту же ошибку

но, изменив его на out.write ( str(item2 )) благодаря TypeError: ожидается объект символьного буфера, я не получите никакой ошибки, вывод показывает это

(массив(['/путь к файлу/test.txt'], dtype='|S29'), массив([0]))

Ниже приведено решение, которое я пытался использовать.

import csv

data = []
def remove_quotes(file):
    for line in file:
        yield line.strip ( '"\n' )
with open ( 'test.txt' ) as f:
    reader = csv.reader ( remove_quotes ( f ) )
    for row in reader:
        data.extend ( row )

Ошибки нет, но и data не генерируется


person nik    schedule 21.12.2016    source источник
comment
Вы можете просто читать из файла, разделять и складывать все в набор.   -  person vks    schedule 21.12.2016
comment
file_name.split ( ',' ). Что вы ожидали от этого?   -  person OneCricketeer    schedule 21.12.2016
comment
См. unique_everseen в разделе рецепты документацию itertools.   -  person Peter Wood    schedule 21.12.2016
comment
@cricket_007 Я ожидал разделить строки на comma   -  person nik    schedule 21.12.2016
comment
@nik, почему ты разделяешь имя файла?   -  person Peter Wood    schedule 21.12.2016
comment
Имя файла не может содержать запятых. Вы использовали неправильную переменную   -  person OneCricketeer    schedule 21.12.2016
comment
@Peter Wood хороший момент, я не знал об этом unique_everseen   -  person nik    schedule 21.12.2016
comment
Также myList — это строка, а не список. Вы присоединили item1 обратно к запятым, которые вы разделили, поэтому по существу воссоздали разделенные запятыми line   -  person OneCricketeer    schedule 21.12.2016
comment
@cricket_007, так ты имеешь в виду, что мне не следовало использовать item1 = file_name.split ( ',' )   -  person nik    schedule 21.12.2016
comment
Зачем тебе 'path to my data/test.txt'.split(',')??   -  person OneCricketeer    schedule 21.12.2016
comment
@cricket_007 Я подумал, что мне следует разделить данные, потому что я хочу, чтобы каждая строка отделялась от другой 'path to my data/test.txt'.split(','), также если я использую myList = " ".join ( map ( str , item1 ) ) the same empty output   -  person nik    schedule 21.12.2016
comment
Нет, вы хотите разделить строки из файла, а не имя файла. Вы использовали неправильную переменную, как я уже говорил несколько раз. Кроме того, строки под item1, вероятно, должны быть с отступом   -  person OneCricketeer    schedule 21.12.2016
comment
@cricket_007 У меня нет проблем с отступами. Я передвинул их вперед, но ничего не изменилось, результат тот же.   -  person nik    schedule 21.12.2016
comment
Я знаю, что вы не получите ошибку, но подумайте об отступе, который у вас есть. myList получает только последний item1, потому что он вне цикла for   -  person OneCricketeer    schedule 21.12.2016
comment
@cricket_007 если я сделаю отступ, как вы говорите, я получу ошибку ValueError: I/O operation on closed file   -  person nik    schedule 21.12.2016


Ответы (3)


stack.txt ниже содержит это:

"India1,India2,myIndia"
"Where,Here,Here"
"Here,Where,India,uyete"
"AFD,TTT"

Ну вот:

from collections import OrderedDict

with open("stack.txt", "r") as f:
    # read your data in from the gist site and strip off any new-line characters
    data = [eval(line.strip()) for line in f.readlines()]
    # get individual words into a list
    individual_elements = [word for row in data for word in row.split(",")]
    # remove duplicates and preserve order
    uniques = OrderedDict.fromkeys(individual_elements)   
    # convert from OrderedDict object to plain list
    final = [word for word in uniques]

print(final)

Что дает это:

['India1', 'India2', 'myIndia', 'Where', 'Here', 'India', 'uyete', 'AFD', 'TTT']

Изменить: чтобы получить желаемый результат, просто распечатайте список в нужном формате:

print("\n".join(final))

Что эквивалентно, с точки зрения вывода, этому:

for x in final:
    print(x)

Что дает это:

India1
India2
myIndia
Where
Here
India
uyete
AFD
TTT
person blacksite    schedule 22.12.2016
comment
Мне уже нравится твой ответ! только одно, можно ли было бы получить вывод в виде столбца без каких-либо ,и ' один под другим? если да, то я принимаю и люблю ваш ответ - person nik; 22.12.2016
comment
final является объектом list, поэтому он имеет символы ' и ,, разделяющие элементы строки. Будет обновляться. - person blacksite; 22.12.2016

Зачем использовать numpy??? и я не уверен, хотите ли вы использовать один и тот же файл для ввода и вывода

#!/usr/bin/env python


# give a name to my data 
inputData = """India1,India2,myIndia
Where,Here,Here   
Here,Where,India,uyete
AFD,TTT"""

# if you want to read the data from a file
#inputData = open(fileName, 'r').readlines()

outputData = ""
tempData = list()
for line in inputData.split("\n"):
    lineStripped = line.strip()
    lineSplit = lineStripped.split(',')
    lineElementsStripped = [element.strip() for element in lineSplit]
    tempData.extend( lineElementsStripped )
tempData = set(tempData)
outputData = "\n".join(tempData)
print("\nInputdata: \n%s" % inputData)
print("\nOutputdata: \n%s" % outputData)
person JDB    schedule 21.12.2016
comment
Важно ли поддерживать порядок? Вероятно, вам следует попросить уточнить вопрос, прежде чем давать ответ. - person Peter Wood; 21.12.2016
comment
Все, что явно не запрошено, для меня не важно. - person JDB; 21.12.2016
comment
Что-то вроде from collections import OrderedDict; tempData = OrderedDict.fromkeys(tempData).keys() должно сохранить порядок. - person blacksite; 21.12.2016
comment
@not_a_robot что это tempData - person nik; 21.12.2016
comment
@JDB порядок важен для меня. Посмотрите на мой вопрос выше. Я показал, как выглядит вывод - person nik; 21.12.2016
comment
@not_a_robot Я хочу принять ваш ответ, если вы его исправите. Я не голосовал против вашего ответа. Единственная проблема, которая у меня есть, заключается в том, что структура данных, которую вы используете, не совпадает с той, которую я просил. Здесь я поделился данными gist.github.com/anonymous/63b1a70e913c1453b0de9d7027b5973a, если вы исправите свой ответ I понравилось и принять ваш ответ - person nik; 22.12.2016
comment
@JDB Я собираюсь принять твой ответ. Пожалуйста, прочтите мой комментарий выше. Кстати, я не минусовал твой ответ - person nik; 22.12.2016
comment
@nik Я добавил ответ выше с реализацией collections.OrderedDict. - person blacksite; 22.12.2016

Похоже, у вас, вероятно, есть файл csv. Вам не нужен numpy для этого, все, что вам нужно, это прилагаемые батареи.

 import csv

 data = []
 with open('test.txt') as f:
     reader = csv.reader(f)
     for row in reader:
         data.extend(row)

Вы можете .extend списки, а не .append к ним. Это в основном как сказать

for thing in row:
    data.append(thing)

Тем не менее, это все равно оставит дубликаты. Если вас не волнует порядок, вы можете просто сделать его set и вызвать .update() вместо расширения:

 data = set()
 with open('test.txt') as f:
     reader = csv.reader(f)
     for row in reader:
         data.extend(row)

А сейчас все уникально. Но если вы заботитесь о порядке, вам придется немного отфильтровать вещи:

unique_data = []
for thing in data:
    if thing not in unique_data:
        unique_data.append(thing)

Если ваш файл test.txt содержит этот текст:

"India1,India2,myIndia     "
"Where,Here,Here   "
"Here,Where,India,uyete"
"AFD,TTT"

И не

India1,India2,myIndia     
Where,Here,Here   
Here,Where,India,uyete
AFD,TTT

Тогда у вас не совсем есть csv. Вы можете либо исправить то, что генерирует ваш CSV, либо вручную удалить кавычки или просто исправить это на лету.

def remove_quotes(file):
    for line in file:
        yield line.strip('"\n')

reader = csv.reader(remove_quotes(f))
person Wayne Werner    schedule 21.12.2016
comment
Ваш файл буквально содержит "foo,bar,thing,quux"\n"next,line,goes,here"\n? Если это так, вы захотите либо исправить свой csv, либо обернуть файл. - person Wayne Werner; 21.12.2016
comment
да, я делюсь примером здесь gist.github.com/anonymous/63b1a70e913c1453b0de9d7027b5973a - person nik; 21.12.2016
comment
Кстати, кавычки, по-видимому, включены в файл ... От OP было несколько вопросов, содержащих эти данные. - person OneCricketeer; 21.12.2016
comment
@nik, тогда тебе определенно нужна обертка remove_quotes. - person Wayne Werner; 21.12.2016
comment
@Wayne Werner, куда поместить последнее remove_quotes?my означает объединение remove_quotes с первым решением, которое вы дали, как передать это читателю? - person nik; 21.12.2016
comment
@Wayne Werner, даже если я исправлю свои данные без кавычек, ваш первый метод не даст никакого результата - person nik; 21.12.2016
comment
@cricket_007 Я написал, как использовал ваше решение выше, которое ничего не генерирует. - person nik; 21.12.2016
comment
@nik Я не дал тебе решения - я указал на логическую ошибку в твоем коде - person OneCricketeer; 21.12.2016
comment
@nik Я предполагал, что вы поместите это в свой существующий код и сделаете свой собственный вывод. - person Wayne Werner; 22.12.2016
comment
@Wayne Werner даже без цитаты ваше решение не работает - person nik; 22.12.2016
comment
не работает, это не минимальный воспроизводимый пример. Если вы не можете объяснить, чего вы ожидаете, то как вы ожидаете, что кто-то вам поможет? - person Wayne Werner; 22.12.2016
comment
@Wayne Werner не работает, значит, я показал вам, я поделился с вами данными и показал, какой результат я ищу. Распечатайте вывод первого кода, который вы дали, вы понимаете, что я имею в виду под неработающим? - person nik; 22.12.2016
comment
@Wayne Werner Это данные gist.github.com/anonymous/63b1a70e913c1453b0de9d7027b5973a Я хочу иметь уникальные строки. Неужели недостаточно ясно??? - person nik; 22.12.2016
comment
Нет, потому что мой код создает уникальные строки, а вы говорите, что это не так. Итак, очевидно, вы имеете в виду что-то совершенно отличное от того, что вы говорите. - person Wayne Werner; 22.12.2016
comment
@Wayne Werner напечатайте ввод и вывод в своем ответе, затем - person nik; 22.12.2016
comment
Если вы не можете понять, как добавить функцию печати, вы можете вернуться к официальный учебник по Python - person Wayne Werner; 22.12.2016