Dostaję te dane z przeszukiwacza i chcesz przenieść go w piękny dataframe.

Teraz, jak mam:

+-----------+------------------------------------------+------------+---------------------+
| HotelName | RoomType                                 | RoomFloor  | RoomPrice           |
+-----------+------------------------------------------+------------+---------------------+
| Hotel1    | Standard,Standard,Standard,Deluxe,Deluxe | 10F,20F    | 100,105,108,200,205 |
| Hotel2    | Standard,Standard,Deluxe,Deluxe,Grande   | 30F,40F,50F| 90,95,250,240,300   |
+-----------+------------------------------------------+------------+---------------------+

W końcu chcę:

+-----------+----------+-----------+-----------+
| HotelName | RoomType | RoomFloor | RoomPrice |
+-----------+----------+-----------+-----------+
| Hotel1    | Standard | 10F       | 100       |
| Hotel1    | Standard | 10F       | 105       |
| Hotel1    | Standard | 10F       | 108       |
| Hotel1    | Deluxe   | 20F       | 200       |
| Hotel1    | Deluxe   | 20F       | 205       |
| Hotel2    | Standard | 30F       | 90        |
| Hotel2    | Standard | 30F       | 95        |
| Hotel2    | Deluxe   | 40F       | 250       |
| Hotel2    | Deluxe   | 40F       | 240       |
| Hotel2    | Grande   | 50F       | 300       |
+-----------+----------+-----------+-----------+

Jestem nowy w Pythonie i nie mogłem tego poradzić. Czy ktoś może pomóc? Wielkie dzięki!

-1
AlexHon 28 czerwiec 2017, 10:08

4 odpowiedzi

Najlepsza odpowiedź

Próbowałem odtworzyć DataFrame, który przypuszczam, powinien być taki sam jak opublikowany:

import pandas as pd

raw_data = {'HotelName': ['Hotel1', 'Hotel2'],
            'RoomType': ['Standard,Standard,Standard,Deluxe,Deluxe', 'Standard,Standard,Deluxe,Deluxe,Grande'],
            'RoomFloor': ['10F,20F', '30F,40F,50F'],
            'RoomPrice': ['100,105,108,200,205', '90,95,250,240,300']}

data = pd.DataFrame(raw_data)

Myślę, że moduł "uporządkowany zestaw" może pomóc, i miejmy nadzieję, że poniższy kod może rozwiązać problem:

from ordered_set import OrderedSet # revise 'orderedset' to 'ordered_set'

cols_ordered = ['HotelName', 'RoomType', 'RoomFloor', 'RoomPrice']
data = data[cols_ordered]

data = data[['HotelName', 'RoomType', 'RoomFloor', 'RoomPrice']].applymap(lambda x: x.split(','))
dummies = data.applymap(lambda x: len(x)).apply(max, 1)

for i in range(len(data)):
    room_type, room_floor = data[['RoomType', 'RoomFloor']].iloc[i]
    type_floor_dict = dict(zip(OrderedSet(room_type), room_floor))
    data['RoomFloor'].iloc[i] = [type_floor_dict[t] for t in room_type]
    data['HotelName'].iloc[i] *= dummies[i]

new_data = [pd.DataFrame(data.loc[i].tolist(), index=cols_ordered).T for i in data.index]
new_data = pd.concat(new_data, ignore_index=True)

print(new_data)
0
AlexHon 4 lipiec 2017, 06:20

Wymyśliłem to rozwiązanie, spójrz

def func(row):
    dic = []
    RoomType = row['RoomType'].split(",")
    RoomPrice = row['RoomPrice'].split(",")
    RoomFloor = row['RoomFloor'].split(",")
    current_room_type = RoomType[0]
    j = 0
    for index, x in enumerate(RoomType):
        if current_room_type != x:
            j+=1
            current_room_type = x
        dic.append({"HotelName": row["HotelName"],"RoomType": x, "RoomPrice": RoomPrice[index], "RoomFloor": RoomFloor[j]})
    return dic

print pd.DataFrame(df.apply(func, axis=1).sum())
-1
Akshay Kandul 28 czerwiec 2017, 08:45

Myślę, że pętle wyprodukuje tutaj bardziej czytelny kod:

data = []
for idx, row in df.iterrows():
    room_types = pd.Series(row['RoomType'].split(','))
    room_floors = row['RoomFloor'].split(',')
    room_prices = row['RoomPrice'].split(',')
    mapping = dict(zip(room_types.unique(), room_floors))
    room_floors = room_types.map(mapping)
    for rm_type, rm_floor, rm_price in zip(room_types, room_floors, room_prices):
        data.append((row['HotelName'], rm_type, rm_floor, rm_price))


pd.DataFrame(data, columns=['HotelName', 'RoomType', 'RoomFloor', 'RoomPrice'])
Out[56]: 
  HotelName  RoomType RoomFloor RoomPrice
0    Hotel1  Standard       10F       100
1    Hotel1  Standard       10F       105
2    Hotel1  Standard       10F       108
3    Hotel1    Deluxe       20F       200
4    Hotel1    Deluxe       20F       205
5    Hotel2  Standard       30F        90
6    Hotel2  Standard       30F        95
7    Hotel2    Deluxe       40F       250
8    Hotel2    Deluxe       40F       240
9    Hotel2    Grande       50F       300

To iryta nad rzędami Dataframe i dla każdego hotelu, generuje listy typów pokoi, podłóg i cen pokojowych. mapping = dict(zip(room_types.unique(), room_floors)) Skrzynie mapowanie między typami pokoi i podłogami. Używanie tego mapowania, room_floors = room_types.map(mapping) tworzy listy równości długości. Teraz, gdy room_types, room_floors i room_prices ma taką samą długość, możesz przede wszystkim itrudzić na nich i dodać każdy rekord jako krotka. Wreszcie ostatnia linia konwertuje listę kanałów do schludnego Dataframe.

0
ayhan 28 czerwiec 2017, 08:10

Rozwiązanie Jeśli są zdefiniowane RoomFloor s osobno:

print (df)
  HotelName                                  RoomType            RoomFloor  \
0    Hotel1  Standard,Standard,Standard,Deluxe,Deluxe  10F,10F,10F,20F,20F   
1    Hotel2    Standard,Standard,Deluxe,Deluxe,Grande  30F,30F,40F,40F,50F   

             RoomPrice  
0  100,105,108,200,205  
1    90,95,250,240,300  

cols = ['RoomType','RoomFloor','RoomPrice']
a = df[cols].apply(lambda x: x.str.split(',', expand=True).stack()).reset_index(1, drop=True)
df = df.drop(cols, axis=1).join(a).reset_index(drop=True)
print (df)
  HotelName  RoomType RoomFloor RoomPrice
0    Hotel1  Standard       10F       100
1    Hotel1  Standard       10F       105
2    Hotel1  Standard       10F       108
3    Hotel1    Deluxe       20F       200
4    Hotel1    Deluxe       20F       205
5    Hotel2  Standard       30F        90
6    Hotel2  Standard       30F        95
7    Hotel2    Deluxe       40F       250
8    Hotel2    Deluxe       40F       240
9    Hotel2    Grande       50F       300
0
jezrael 28 czerwiec 2017, 07:57