2015-11-13 43 views
5

Tôi có tập tin với dòng CSV trông giống như:liệu munging trong gấu trúc

ID,98.4,100M,55M,65M,75M,100M,75M,65M,100M,98M,100M,100M,92M,0#,0N#, 

tôi có thể đọc nó với

#!/usr/bin/env python 

import pandas as pd 
import sys 

filename = sys.argv[1] 
df = pd.read_csv(filename) 

Cho một cột cụ thể, tôi muốn chia các hàng bởi ID và sau đó xuất độ lệch chuẩn và trung bình cho từng ID.

Vấn đề đầu tiên của tôi là, làm cách nào tôi có thể xóa tất cả các phần không phải là số từ các số như "100M" và "0N #" phải là 100 và 0 tương ứng.

Tôi cũng đã cố gắng lặp qua các tiêu đề có liên quan và sử dụng

df[header].replace(regex=True,inplace=True,to_replace=r'\D',value=r'') 

như đề xuất trong Pandas DataFrame: remove unwanted parts from strings in a column.

Tuy nhiên điều này thay đổi 98,4 vào 984.

+0

có thể trùng lặp của [Pandas DataFrame: loại bỏ các phần không mong muốn từ các chuỗi trong một cột] (http: // stackoverflow.com/questions/13682044/pandas-dataframe-remove-unwanted-parts-from-strings-in-a-column) – Evert

+0

@Evert Đã thêm bản chỉnh sửa để hiển thị cách tôi cần đối phó với các dấu thập phân. – eleanora

+0

Bản sao tôi liệt kê đề nghị sử dụng 'rstrip', với các ký tự bạn muốn xóa. Vì vậy ... 'rstrip ('MN #')' nên hoạt động tốt cho đầu vào của bạn, sử dụng lambda được đề xuất trong bản sao (tất nhiên, bạn có thể bỏ qua phần 'lstrip'). – Evert

Trả lời

3

sử dụng str.extract:

In [356]: 
import io 
import pandas as pd 
t="""ID,98.4,100M,55M,65M,75M,100M,75M,65M,100M,98M,100M,100M,92M,0#,0N#""" 
df = pd.read_csv(io.StringIO(t), header=None) 
df 

Out[356]: 
    0  1  2 3 4 5  6 7 8  9 10 11 12 13 \ 
0 ID 98.4 100M 55M 65M 75M 100M 75M 65M 100M 98M 100M 100M 92M 

    14 15 
0 0# 0N# 

In [357]: 
for col in df.columns[2:]: 
    df[col] = df[col].str.extract(r'(\d+)').astype(int) 
df 

Out[357]: 
    0  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
0 ID 98.4 100 55 65 75 100 75 65 100 98 100 100 92 0 0 

Nếu bạn có số float sau đó bạn có thể sử dụng regex sau:

In [379]: 
t="""ID,98.4,100.50M,55.234M,65M,75M,100M,75M,65M,100M,98M,100M,100M,92M,0#,0N#""" 
df = pd.read_csv(io.StringIO(t), header=None) 
df 

Out[379]: 
    0  1  2  3 4 5  6 7 8  9 10 11 \ 
0 ID 98.4 100.50M 55.234M 65M 75M 100M 75M 65M 100M 98M 100M 

    12 13 14 15 
0 100M 92M 0# 0N# 

In [380]:  
for col in df.columns[2:]: 
    df[col] = df[col].str.extract(r'(\d+\.?\d+)').astype(np.float) 
df 

Out[380]: 
    0  1  2  3 4 5 6 7 8 9 10 11 12 13 14 15 
0 ID 98.4 100.5 55.234 65 75 100 75 65 100 98 100 100 92 NaN NaN 

nên (\d+\.?\d+) tìm kiếm nhóm chứa \d+ 1 hoặc nhiều chữ số với \.? điểm thập phân tùy chọn và \d+ 1 hoặc thêm nhiều chữ số sau dấu thập phân

EDIT

OK thay đổi nội dung mẫu biểu thức chính của tôi:

In [408]: 
t="""Name,97.7,0A,0A,65M,0A,100M,5M,75M,100M,90M,90M,99M,90M,0#,0N#""" 
df = pd.read_csv(io.StringIO(t), header=None) 
df 

Out[408]: 
    0  1 2 3 4 5  6 7 8  9 10 11 12 13 14 \ 
0 Name 97.7 0A 0A 65M 0A 100M 5M 75M 100M 90M 90M 99M 90M 0# 

    15 
0 0N# 

In [409]:  
for col in df.columns[2:]: 
    df[col] = df[col].str.extract(r'(\d+\.*\d*)').astype(np.float) 
df 

Out[409]: 
    0  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
0 Name 97.7 0 0 65 0 100 5 75 100 90 90 99 90 0 0 
+0

df = pd.read_csv (io.StringIO (t), tiêu đề = Không) LoạiError: initial_value phải là unicode hoặc None, không str – eleanora

+0

Bỏ qua bit 'io.StringIO' đây chỉ là tôi đọc trong văn bản của bạn dưới dạng đối tượng tệp trong trường hợp của bạn 'df = pd.read_csv (tên tệp)' là tốt – EdChum

+0

Nếu đây là toàn bộ tệp "Tên", 97,7,0A, 0A, 65M, 0A, 100M, 5M, 75M, 100M, 90M, 90M, 99M, 90M, 0 #, 0N #, "Mã của bạn cho tôi" 0 Tên NaN NaN NaN 65 NaN 100 NaN 75 100 90 90 99 90 NaN NaN NaN " – eleanora

2

My first problem is, how can I remove all the non-numeric parts from the numbers such as "100M" and "0N#" which should be 100 and 0 respectively.

import re 
df = pd.read_csv(yourfile, header=None) 
df.columns = ['ID'] + list(df.columns)[1:] 
df = df.stack().apply(lambda v: re.sub('[^0-9]','', v) 
       if isinstance(v, str) else v).astype(float).unstack() 
df.groupby('ID').agg(['std', 'mean']) 

đây .stack() biến đổi dataframe thành một Series, .apply() gọi lambda cho mỗi giá trị, re.sub() xóa mọi ký tự không phải là số, .astype() chuyển đổi thành số và unstack() biến Series trở lại thành một khung dữ liệu. Điều này hoạt động tốt cho cả số nguyên và số dấu phẩy động.

Given a particular column, I would like to split the rows by ID and then output the mean and standard deviation for each ID.

# for all columns 
df.groupby('ID').agg(['std', 'mean']) 
# for specific column 
df.groupby('ID')['<colname>'].agg(['std', 'mean']) 

output dataframe

Dưới đây là các dữ liệu được sử dụng trong ví dụ:

from StringIO import StringIO 
s=""" 
1,98.4,100M,55M,65M,75M,100M,75M,65M,100M,98M,100M,100M,92M,0#,0N#, 
1,98.4,100M,55M,65M,75M,100M,75M,65M,100M,98M,100M,100M,92M,0#,0N#, 
2,98.4,100M,55M,65M,75M,100M,75M,65M,100M,98M,100M,100M,92M,0#,0N#, 
2,98.4,100M,55M,65M,75M,100M,75M,65M,100M,98M,100M,100M,92M,0#,0N#, 
""" 
yourfile = StringIO(s) 
Các vấn đề liên quan