Список в фрейм данных, список в несколько списков, один столбец в фрейм данных - PullRequest
0 голосов
/ 27 мая 2020

Все еще разбираюсь в программировании, помощь приветствуется! У меня есть единственный столбец информации, который я хотел бы преобразовать в фрейм данных. Я мог бы транспонировать его, но информация об адресе различается, это либо 2 строки, либо 3 строки (у некоторых есть номера наборов и т. Д. c).

Обычно это выглядит так.

name x,  
ID 1,  
123-xyz,  
ID 2,  
abcdefg,  
ACTIVITY,  
ggg,  
TYPE,  
C,  
COUNTY,  
orange county,  
ADDRESS,  
123 stack st,  
city state zip,  
PHONE,  
111-111-1111,  
EXPIRES,  
date,  
name y,  
ID 1,  
456-abc,  
ID 2,  
cvbnmnb,  
ACTIVITY,  
ggg,  
TYPE,  
A,  
COUNTY,  
dakota county,  
ADDRESS,  
234 overflow st, 
lot a,   
city state zip,  
PHONE,  
000-000-0000,  
EXPIRES,  
date,  
name z,  
...,  

Я думал о создании новых списков для всех желаемых столбцов и условном добавлении значений с помощью для l oop.

for i in list  

if value = ID  
 append previous value to name list  
 append next value to ID list  

elif value = phone  
 send next value to phone   

elif value = address  
 evaluate 3 rows down  
  if value = phone  
   concatenate previous two values and append to address list  
  if value != phone  
   concatenate current and previous 2 values and append to address list  

else print error message  

Будет ли это достаточно эффективным вариантом для списков около ~ 20 000 значений?
Я действительно не знаю, как это написать, я использую python в блокноте jupyter. Ищете решения, но также хотите узнать больше!

-EDIT-

Некоторое время пользователь предложил l oop, и исходный образец данных, который я дал, был упрощен и содержал 4 поля. Мой настоящий набор содержал 9, и я попытался поиграть, но, к сожалению, не смог понять это самостоятельно.

count = 0 #Pointer to start of a cluster
lengthdf = len(df) #Getting the length of the existing dataframe to use it as the terminating condition
while count != lengthdf: 
    name = id1 = id2 = activity = type = county = address = phone = expires = "" #Reset the fields for every cluster of information
    name = df[0][count] #Name is always the first line of cluster
    id1 = df[0][count+2] #id is always third line of cluster
    id2 = df[0][count+4]
    activity = df[0][count+6]
    type = df[0][count+8]
    county = df[0][count+10]
    n=11
    while df[0][count+n] != "Phone": #While row is not 'PHONE', everything else in between is the address, appended and separated by comma.
        address=address+df[0][count+n]+", "
        n+=1
    phone = df[0][count+n+1] #Phone number is always the row after 'PHONE', and is only of 1 line.
    expires = df[0][count+n+3]
    n+=2
    newdf = newdf.append({'NAME': name, 'ID 1': id1, 'ID 2': id2, 'ACTIVITY': activity, 'TYPE': type, 'COUNTY': county, 'ADDRESS': address, 'Phone': phone, 'Expires': expires}, ignore_index=True) #Append the data into the new dataframe
    count=count+n

1 Ответ

0 голосов
/ 28 мая 2020

Судя по предоставленному вами псевдокоду, вы, кажется, вкратце понимаете, что вам нужно делать!

Я предполагаю, что ваш файл xlsx без запятых выглядит примерно так. enter image description here

Основываясь на данных вашего образца, это то, что я могу вам предложить. Я буду называть данные каждого пользователя «кластером».

Этот код работает при нескольких предположениях:

  1. Поле PHONE всегда содержит только 1 строку данных
  2. Есть полные данные для всего кластера (или если данные отсутствуют, в следующей строке имеется пробел).
  3. Данные всегда находятся в этом конкретном порядке (т.е. имя, идентификатор, адрес, телефон)

count будет как указатель на начало кластера, а n будет смещением от count. Прочтите комментарии для объяснений.

import pandas as pd
df = pd.read_excel (r'test.xlsx', header = None) #Import xlsx file
newdf = pd.DataFrame(columns=['name', 'id', 'address', 'phone']) #Creating blank dataframe

count = 0 #Pointer to start of a cluster
lengthdf = len(df) #Getting the length of the existing dataframe to use it as the terminating condition
while count != lengthdf: 
    this_add = this_name = this_id = this_phone = "" #Reset the fields for every cluster of information
    this_name = df[0][count] #Name is always the first line of cluster
    this_id = df[0][count+2] #id is always third line of cluster
    n=4
    while df[0][count+n] != "PHONE": #While row is not 'PHONE', everything else in between is the address, appended and separated by comma.
        this_add=this_add+df[0][count+n]+", "
        n+=1
    this_phone = df[0][count+n+1] #Phone number is always the row after 'PHONE', and is only of 1 line.
    n+=2
    newdf = newdf.append({'name': this_name, 'id': this_id, 'address': this_add, 'phone':this_phone}, ignore_index=True) #Append the data into the new dataframe
    count=count+n

Что касается производительности, я, честно говоря, не думаю, что можно провести большую оптимизацию, учитывая характер набора данных (я могу ошибаться). Если вы поняли, что мое решение довольно "жестко запрограммировано", чтобы уменьшить потребность в if-else операторах, но 20 000 строк не должны стать большой проблемой для Jupyter Notebook. Может занять пару минут, но все должно быть в порядке.

Надеюсь, это поможет вам начать работу над другим сценарием ios, с которым вы можете столкнуться с оставшимися наборами данных!

...