Read csv Pandas spaces multiples

enter image description here

I have a very similar dataset in csv file with two column,

For Example: In first row and first column Item:"Betarraga paquete 5 unidades"

In first row and second column qty:1

Item    qty
Betarraga paquete 5 unidades    1
Betarraga paquete 5 unidades    2
Betarraga paquete 5 unidades    1
Betarraga paquete 5 unidades    1
CANASTA PEQUEÑA 1
Cebolla Nueva 20 unidades   1
Cebolla Nueva 20 unidades   2
Cebolla Nueva 20 unidades   1
Cebollin atado de 3 2
Cebollin atado de 3 2
Cebollin atado de 3 3
Cebollin atado de 3 1
Cebollin atado de 3 1
Cebollin atado de 3 1
Cebollin atado de 3 1

II should like to read with pandas, but using:

     df1 = pd.read_csv(r'pedidos4.csv',sep='\s+',encoding='utf-8',error_bad_lines=False)  

This only returns 2 column but first word in the first column input as rowname

enter image description here

  df.shape
  (15, 2)

Upvotes: 0

Views: 82

Answers (2)

Akshay Sehgal
Akshay Sehgal

Reputation: 19322

I am able to read the exact text block you have posted as 2 columns. Please try using sep='\s\s+'

After that, you can write a function that takes in a row, checks if qty is null, fixes the qty column and the Item column and returns the row. Then you can apply it over the df over axis=1

Item    qty
Betarraga paquete 5 unidades    1
Betarraga paquete 5 unidades    2
Betarraga paquete 5 unidades    1
Betarraga paquete 5 unidades    1
CANASTA PEQUEÑA 1
Cebolla Nueva 20 unidades   1
Cebolla Nueva 20 unidades   2
Cebolla Nueva 20 unidades   1
Cebollin atado de 3 2
Cebollin atado de 3 2
Cebollin atado de 3 3
Cebollin atado de 3 1
Cebollin atado de 3 1
Cebollin atado de 3 1
Cebollin atado de 3 1
df = pd.read_clipboard('\s\s+')

#Then use fix to fix the qty values

def fix(row):
    if pd.isnull(row['qty']):
        row['qty']=row['Item'][-1:]
        row['Item']=row['Item'][:-1].strip()
    return row

fixed_df = df.apply(fix, axis=1)
print(fixed_df)
                            Item qty
0   Betarraga paquete 5 unidades   1
1   Betarraga paquete 5 unidades   2
2   Betarraga paquete 5 unidades   1
3   Betarraga paquete 5 unidades   1
4               CANASTA PEQUEÑA    1
5      Cebolla Nueva 20 unidades   1
6      Cebolla Nueva 20 unidades   2
7      Cebolla Nueva 20 unidades   1
8           Cebollin atado de 3    2
9           Cebollin atado de 3    2
10          Cebollin atado de 3    3
11          Cebollin atado de 3    1
12          Cebollin atado de 3    1
13          Cebollin atado de 3    1
14          Cebollin atado de 3    1

Upvotes: 2

piterbarg
piterbarg

Reputation: 8219

I assume you want the last element of each line to be column2, and the rest in column 1. So you may have to do it manually because the amount of whitespace is inconsistent for different rows and I do not think the standard read_csv approach is easy to make work. So here is an alternative

This is our data

file = StringIO(
"""Item    qty
Betarraga paquete 5 unidades    1
Betarraga paquete 5 unidades    2
Betarraga paquete 5 unidades    1
Betarraga paquete 5 unidades    1
CANASTA PEQUEÑA 1
Cebolla Nueva 20 unidades   1
Cebolla Nueva 20 unidades   2
Cebolla Nueva 20 unidades   1
Cebollin atado de 3 2
Cebollin atado de 3 2
Cebollin atado de 3 3
Cebollin atado de 3 1
Cebollin atado de 3 1
Cebollin atado de 3 1
Cebollin atado de 3 1
""")

#If 'myfile.txt' is where this data is, you should replace the above with
# file = open('myfile.txt', 'r')

Then we read file line by line, split the line at white space, use the last token as column 2 and the rest as column1, and stick in a dataframe

col1 = []
col2 = []
for line in file:
    tokens = line.split()
    c1 = ' '.join(tokens[:-1])
    c2 = tokens[-1]
    col1.append(c1)
    col2.append(c2)

df = pd.DataFrame({col1[0] : col1[1:], col2[0] : col2[1:]})
df['qty'] = df['qty'].astype(int)
df

produces


    Item                            qty
--  ----------------------------  -----
 0  Betarraga paquete 5 unidades      1
 1  Betarraga paquete 5 unidades      2
 2  Betarraga paquete 5 unidades      1
 3  Betarraga paquete 5 unidades      1
 4  CANASTA PEQUEÑA                   1
 5  Cebolla Nueva 20 unidades         1
 6  Cebolla Nueva 20 unidades         2
 7  Cebolla Nueva 20 unidades         1
 8  Cebollin atado de 3               2
 9  Cebollin atado de 3               2
10  Cebollin atado de 3               3
11  Cebollin atado de 3               1
12  Cebollin atado de 3               1
13  Cebollin atado de 3               1
14  Cebollin atado de 3               1

Upvotes: 0

Related Questions