How to convert following list into pandas dataframe?

Viewed 94
lst = ['Hospital Name: ', 'Methodist LEADING MEDICINE', 'Hospital Address: ', 'PO Box 3133 Houston, TX 77253-3133', 'Total Charges: ', 'Hospital Name: ', 'Hospital Address: ', 'PO Box 3133 Houston, TX 77253-3133', 'Total Charges: ', 'Hospital Name: ', 'Hospital Address: ', 'PO Box 3133 Houston, TX 77253-3133', 'Total Charges: ', '131,975.58', 'Hospital Name: ', 'Houston Methodist Sugar Land Hospital', 'Hospital Address: ', '16655 Southwest Frwy Sugar Land TX 77479', 'Total Charges: ']

I want output pandas dataframe like

Hospital Name:                   Hospital Address:                         Total Charges:
Methodist LEADING MEDICINE       PO Box 3133 Houston, TX 77253-3133        None
None                             PO Box 3133 Houston, TX 77253-3133        None
None                             PO Box 3133 Houston, TX 77253-3133        131,975.58
Houston Methodist Sugar          16655 Southwest Frwy Sugar Land TX 77479  None
Land Hospital

How I can do this by using python

6 Answers

Just use these code and you can get what you want

import pandas as pd

lst = ["Hospital Name: ", "Methodist LEADING MEDICINE", "Hospital Address: ", "PO Box 3133 Houston, TX 77253-3133", "Total Charges: ", "Hospital Name: ", "Hospital Address: ", "PO Box 3133 Houston, TX 77253-3133", "Total Charges: ", "Hospital Name: ", "Hospital Address: ", "PO Box 3133 Houston, TX 77253-3133", "Total Charges: ", "131,975.58", "Hospital Name: ", "Houston Methodist Sugar Land Hospital", "Hospital Address: ", "16655 Southwest Frwy Sugar Land TX 77479", "Total Charges: "]
columns = ["Hospital Name: ", "Hospital Address: ", "Total Charges: "]

data = {
    "Hospital Name: ": [],
    "Hospital Address: ": [],
    "Total Charges: ": [],
}

for i in range(len(lst)):
    if lst[i] in columns:
        if i+1 > len(lst)-1 or lst[i+1] in columns:
            data[lst[i]].append(None)
        else:
            data[lst[i]].append(lst[i+1])

df = pd.DataFrame(data, columns=columns)

enter image description here

import pandas as pd


lst = ['Hospital Name: ', 'Methodist LEADING MEDICINE', 'Hospital Address: ', 'PO Box 3133 Houston, TX 77253-3133', 'Total Charges: ', 'Hospital Name: ', 'Hospital Address: ', 'PO Box 3133 Houston, TX 77253-3133', 'Total Charges: ', 'Hospital Name: ', 'Hospital Address: ', 'PO Box 3133 Houston, TX 77253-3133', 'Total Charges: ', '131,975.58', 'Hospital Name: ', 'Houston Methodist Sugar Land Hospital', 'Hospital Address: ', '16655 Southwest Frwy Sugar Land TX 77479', 'Total Charges: ']
items, headers = [], ['Hospital Name: ', 'Hospital Address: ', 'Total Charges: ']

for index, item in enumerate(lst):
    if index == len(lst) - 1:
        if item in headers:
            items.extend([item, None])
        else:
            items.append(item)

    else:
        if not (item in headers and lst[index+1] in headers):
            items.append(item)
        else:
            items.extend([item, None])

print(pd.DataFrame({"Hospital Name: ": items[1::6], "Hospital Address: ": items[3::6], "Total Charges: ": items[5::6]}))

use from this code:

first ensure that the end of list we have a valid member the create each of list for column with a for loop and O(n). then create dataframe

import pandas as pd

if lst[-1].find(':')>-1:
    lst.append('')
name , address , charge = [],[],[]
for i in range(len(lst)-1):
    if lst[i] == 'Hospital Name: ' and lst[i+1].find(':')==-1: 
        name.append(lst[i+1])
    if lst[i] == 'Hospital Name: ' and lst[i+1].find(':')>-1: 
        name.append('')
        
    if lst[i] == 'Hospital Address: ' and lst[i+1].find(':')==-1: 
        address.append(lst[i+1])
    if lst[i] == 'Hospital Address: ' and lst[i+1].find(':')>-1: 
        address.append('')
        
    if lst[i] == 'Total Charges: ' and lst[i+1].find(':')==-1: 
        charge.append(lst[i+1])
    if lst[i] == 'Total Charges: ' and lst[i+1].find(':')>-1: 
        charge.append('')

data = {'hospital name': name, 'hospital address': address, 'total charge': charge}        
df = pd.DataFrame(data)
print(df)

or via dictionaries

import pandas as pd

lst = ['Hospital Name: ', 'Methodist LEADING MEDICINE', 'Hospital Address: ', 'PO Box 3133 Houston, TX 77253-3133', 'Total Charges: ', 'Hospital Name: ', 'Hospital Address: ', 'PO Box 3133 Houston, TX 77253-3133', 'Total Charges: ', 'Hospital Name: ', 'Hospital Address: ', 'PO Box 3133 Houston, TX 77253-3133', 'Total Charges: ', '131,975.58', 'Hospital Name: ', 'Houston Methodist Sugar Land Hospital', 'Hospital Address: ', '16655 Southwest Frwy Sugar Land TX 77479', 'Total Charges: ']
ordered_headers = ['Hospital Name: ', 'Hospital Address: ', 'Total Charges: ']
items = []
prev_item_dict = None

for index, item in enumerate(lst):
    if item == ordered_headers[0]:
        if prev_item_dict is not None:
            # append previously created to the list of items
            items.append(prev_item_dict)
        prev_item_dict = {}
    if item in ordered_headers:
        value_for_index = lst[index+1] if index+1 < len(lst) and lst[index+1] not in ordered_headers else None
        # assign the (key: value) pair per each future row
        prev_item_dict[item] = value_for_index
# add last item
if prev_item_dict is not None:
    items.append(prev_item_dict)

pd.DataFrame(items)

You could do it like this:

lst = ['Hospital Name: ', 'Methodist LEADING MEDICINE', 'Hospital Address: ', 'PO Box 3133 Houston, TX 77253-3133', 'Total Charges: ', 'Hospital Name: ', 'Hospital Address: ', 'PO Box 3133 Houston, TX 77253-3133', 'Total Charges: ', 'Hospital Name: ', 'Hospital Address: ', 'PO Box 3133 Houston, TX 77253-3133', 'Total Charges: ', '131,975.58', 'Hospital Name: ', 'Houston Methodist Sugar Land Hospital', 'Hospital Address: ', '16655 Southwest Frwy Sugar Land TX 77479', 'Total Charges: ']

dic = {}
cols = ['Hospital Name: ', 'Hospital Address: ', 'Total Charges: ']
l = len(lst)
for idx, elem in enumerate(lst):
    if elem in cols:
        (dic.setdefault(elem, [])
         .append(lst[idx+1] if ((not idx>=l-1) and (not lst[idx+1] in cols)) else None))
df = pd.DataFrame(dic)

Output df:

                         Hospital Name:                         Hospital Address:  Total Charges: 
0             Methodist LEADING MEDICINE        PO Box 3133 Houston, TX 77253-3133            None
1                                   None        PO Box 3133 Houston, TX 77253-3133            None
2                                   None        PO Box 3133 Houston, TX 77253-3133      131,975.58
3  Houston Methodist Sugar Land Hospital  16655 Southwest Frwy Sugar Land TX 77479            None

For fun, here is a pure pandas solution that is agnostic on the column headers (just relies on the fact that headers end with ":"):

s = pd.Series(lst)
# which items end with ":"?
m = s.str.contains(r':\s*$')

# group together same entries
g = s.groupby(s.where(m).ffill(), sort=False).ngroup()
# determine index
idx = g.where(m).eq(0).cumsum()

# reshape
out = (pd
 .DataFrame({'A': s, 'B': m, 'C': g, 'D': idx})
 .pivot(['C', 'D'], 'B', 'A')
 .set_index(True, append=True)[False]
 .droplevel(0).unstack(True)
 .rename_axis(index=None, columns=None)
)

output:

                         Hospital Address:                         Hospital Name:  Total Charges: 
1        PO Box 3133 Houston, TX 77253-3133             Methodist LEADING MEDICINE             NaN
2        PO Box 3133 Houston, TX 77253-3133                                    NaN             NaN
3        PO Box 3133 Houston, TX 77253-3133                                    NaN      131,975.58
4  16655 Southwest Frwy Sugar Land TX 77479  Houston Methodist Sugar Land Hospital             NaN
Related