2017-12-30 180 views
5

Như đầu vào tôi có hai dataframes:Hợp nhất hai dataframes với dữ liệu khoảng thời gian trong một trong số họ

data1 = [{'code':100}, {'code':120}, {'code':110}] 
data1 = pd.DataFrame(data1) 

    code 
0 100 
1 120 
2 110 

data2 = [{'category':1, 'l_bound':99, 'r_bound':105},{'category':2, 'l_bound':107, 'r_bound':110},{'category':3, 'l_bound':117, 'r_bound':135}] 
data2 = pd.DataFrame(data2) 

    category l_bound r_bound 
0   1  99  105 
1   2  107  110 
2   3  117  135 

Tôi muốn nhận được vào cuối những dataframe sau, với cột bổ sung trong dataframe đầu tiên như một số loại nếu mã nằm trong khoảng thời gian tương ứng:

code category 
0 100   1 
1 120   3 
2 110   2 

Khoảng thời gian là ngẫu nhiên và các khung dữ liệu ban đầu là khá lớn. Looping với itertuples là quá chậm. Bất kỳ giải pháp pythonic?

+0

trăn tinh khiết - https://eval.in/928533 – splash58

+1

@AntonvBR Tôi đã không nhìn kỹ vào ví dụ này, nhưng vấn đề (và câu trả lời) giữa hai dường như giống hệt nhau ... –

+0

** Quan sát hữu ích **: Các giải pháp dưới đây có thể không hoạt động nếu dữ liệu không ở định dạng thích hợp. Đảm bảo rằng 'dữ liệu1' và' dữ liệu2' là số nguyên. Cũng có thể có các định dạng hỗn hợp trong một số cột của tập dữ liệu gốc (ví dụ: '' mã ':' 123a''). Để loại bỏ nó chỉ cần thêm 'data1 = data1 [pd.to_numeric (data1 ['code'], errors = 'coerce'). Notnull()] data1 ['code'] = pd.to_numeric (data1 ['code ']) ' –

Trả lời

1

Tạo lại dữ liệu:

import pandas as pd 

data1 = [{'code':100}, {'code':120}, {'code':113}] 
data2 = [{'category':1, 'l_bound':99, 'r_bound':105}, 
     {'category':2, 'l_bound':107, 'r_bound':110}, 
     {'category':3, 'l_bound':117, 'r_bound':135}] 

data1 = pd.DataFrame(data1) 
data2 = pd.DataFrame(data2) 

@ câu trả lời cᴏʟᴅsᴘᴇᴇᴅ (ưa thích), đi theo liên kết trùng lặp:

idx = pd.IntervalIndex.from_arrays(data2['l_bound'], data2['r_bound'], closed='both') 
category = data2.loc[idx.get_indexer(data1.code), 'category'] 

data1['category'] = category.values 

Đây là một cách tiếp cận khác nhau. Tạo bản đồ có giá trị trong phạm vi và danh mục.

# Create a map 
d = {i:k for k,v in data2.set_index('category').to_dict('i').items() 
    for i in range(v['l_bound'],v['r_bound']+1)} 

# Use map to add new column 
data1['category'] = data1.code.map(d) 

Cuối cùng

print(data1) 

Returns:

code category 
0 100  1.0 
1 120  3.0 
2 113  NaN 

Nếu bạn muốn int chúng ta có thể làm điều này:

data1.code.map(d).fillna(-1).astype(int) # -1 meaning no match 

Và w e nhận được:

code category 
0 100   1 
1 120   3 
2 113  -1 
+0

Tôi không biết tại sao, nhưng IntervalIndex dường như không hoạt động. Tôi có một lỗi "AttributeError: 'module' đối tượng không có thuộc tính 'IntervalIndex'" –

+0

Có thể bạn không có phiên bản gấu trúc mới nhất. –

+0

Vâng, đó là sự thật. –

Các vấn đề liên quan