Urutkan string dalam kolom dan cetak grafik

Saya memiliki kerangka data, tetapi semua string diduplikasi dan ketika saya mencoba mencetak grafik, itu berisi kolom duplikat. Saya mencoba menghapusnya, tetapi grafik saya salah dicetak. CSV saya di sini.

Bingkai Data common_users:

     used_at  common users                     pair of websites
0       2014          1364                   avito.ru and e1.ru
1       2014          1364                   e1.ru and avito.ru
2       2014          1716                 avito.ru and drom.ru
3       2014          1716                 drom.ru and avito.ru
4       2014          1602                 avito.ru and auto.ru
5       2014          1602                 auto.ru and avito.ru
6       2014           299           avito.ru and avtomarket.ru
7       2014           299           avtomarket.ru and avito.ru
8       2014           579                   avito.ru and am.ru
9       2014           579                   am.ru and avito.ru
10      2014           602             avito.ru and irr.ru/cars
11      2014           602             irr.ru/cars and avito.ru
12      2014           424       avito.ru and cars.mail.ru/sale
13      2014           424       cars.mail.ru/sale and avito.ru
14      2014           634                    e1.ru and drom.ru
15      2014           634                    drom.ru and e1.ru
16      2014           475                    e1.ru and auto.ru
17      2014           475                    auto.ru and e1.ru
.....

Anda dapat melihat bahwa nama situs web terbalik. Saya mencoba mengurutkannya berdasarkan pair of websites dengan saya punya KeyError. Saya menggunakan kode

df = pd.read_csv("avito_trend.csv", parse_dates=[2])

def f(df):
    dfs = []
    for x in [list(x) for x in itertools.combinations(df['address'].unique(), 2)]:

        c1 = df.loc[df['address'].isin([x[0]]), 'ID']
        c2 = df.loc[df['address'].isin([x[1]]), 'ID']
        c = pd.Series(list(set(c1).intersection(set(c2))))
        #add inverted intersection c2 vs c1
        c_invert = pd.Series(list(set(c2).intersection(set(c1))))
        dfs.append(pd.DataFrame({'common users':len(c), 'pair of websites':' and '.join(x)}, index=[0]))
        #swap values in x
        x[1],x[0] = x[0],x[1]
        dfs.append(pd.DataFrame({'common users':len(c_invert), 'pair of websites':' and '.join(x)}, index=[0]))
    return pd.concat(dfs)

common_users = df.groupby([df['used_at'].dt.year]).apply(f).reset_index(drop=True, level=1).reset_index()

graph_by_common_users = common_users.pivot(index='pair of websites', columns='used_at', values='common users')
#sort by column 2014
graph_by_common_users = graph_by_common_users.sort_values(2014, ascending=False)

ax = graph_by_common_users.plot(kind='barh', width=0.5, figsize=(10,20))
[label.set_rotation(25) for label in ax.get_xticklabels()]


rects = ax.patches 
labels = [int(round(graph_by_common_users.loc[i, y])) for y in graph_by_common_users.columns.tolist() for i in graph_by_common_users.index] 
for rect, label in zip(rects, labels): 
    height = rect.get_height() 
    ax.text(rect.get_width() + 3, rect.get_y() + rect.get_height(), label, fontsize=8)

plt.show()

Grafik saya terlihat seperti:

Grafik saya terlihat seperti


person ldevyataykina    schedule 20.03.2016    source sumber
comment
dapatkah Anda memberikan daftar label yang diharapkan, karena tidak jelas apa yang ingin Anda capai?   -  person MaxU    schedule 20.03.2016
comment
Sekarang saya punya masalah lain. Saya meneruskan array dan mendapatkan rects = ax1.patches labels = ["%d" % i for i in time['time online'].round()] for rect, label in zip(rects, labels): print rect, label height = rect.get_height() ax1.text(rect.get_x() + rect.get_width()/2, height + 5, label, ha='center', va='bottom') Saya menjelaskan masalah saya di pertanyaan   -  person ldevyataykina    schedule 20.03.2016


Jawaban (2)


Anda dapat menambahkan kolom baru sort terlebih dahulu di fungsi f, lalu mengurutkan nilai berdasarkan kolom pair of websites dan terakhir drop_duplicates menurut kolom used_at dan sort:

import pandas as pd
import itertools

df = pd.read_csv("avito_trend.csv", 
                      parse_dates=[2])


def f(df):
    dfs = []
    i = 0
    for x in [list(x) for x in itertools.combinations(df['address'].unique(), 2)]:
        i += 1
        c1 = df.loc[df['address'].isin([x[0]]), 'ID']
        c2 = df.loc[df['address'].isin([x[1]]), 'ID']
        c = pd.Series(list(set(c1).intersection(set(c2))))
        #add inverted intersection c2 vs c1
        c_invert = pd.Series(list(set(c2).intersection(set(c1))))
        dfs.append(pd.DataFrame({'common users':len(c), 'pair of websites':' and '.join(x), 'sort': i}, index=[0]))
        #swap values in x
        x[1],x[0] = x[0],x[1]
        dfs.append(pd.DataFrame({'common users':len(c_invert), 'pair of websites':' and '.join(x), 'sort': i}, index=[0]))
    return pd.concat(dfs)

common_users = df.groupby([df['used_at'].dt.year]).apply(f).reset_index(drop=True, level=1).reset_index()
common_users = common_users.sort_values('pair of websites')
common_users = common_users.drop_duplicates(subset=['used_at','sort']) 
#print common_users

graph_by_common_users = common_users.pivot(index='pair of websites', columns='used_at', values='common users')
#print graph_by_common_users

#change order of columns
graph_by_common_users = graph_by_common_users[[2015,2014]]
graph_by_common_users = graph_by_common_users.sort_values(2014, ascending=False)

ax = graph_by_common_users.plot(kind='barh', width=0.5, figsize=(10,20))
[label.set_rotation(25) for label in ax.get_xticklabels()]

rects = ax.patches 
labels = [int(round(graph_by_common_users.loc[i, y])) for y in graph_by_common_users.columns.tolist() for i in graph_by_common_users.index] 
for rect, label in zip(rects, labels): 
    height = rect.get_height() 
    ax.text(rect.get_width() + 20, rect.get_y() - 0.25 + rect.get_height(), label, fontsize=8) 

#sorting values of legend
handles, labels = ax.get_legend_handles_labels()
# sort both labels and handles by labels
labels, handles = zip(*sorted(zip(labels, handles), key=lambda t: t[0]))
ax.legend(handles, labels)     

Grafik saya:

grafik

Sunting:

Komentar adalah:

Mengapa Anda membuat c_invert dan x1,x[0] = x[0] ,x1

Karena kombinasi tahun 2014 dan 2015 berbeda - nilai 4 hilang di kolom pertama dan 4 di kolom kedua:

used_at                                2015    2014
pair of websites                                   
avito.ru and drom.ru                 1491.0  1716.0
avito.ru and auto.ru                 1473.0  1602.0
avito.ru and e1.ru                   1153.0  1364.0
drom.ru and auto.ru                     NaN   874.0
e1.ru and drom.ru                     539.0   634.0
avito.ru and irr.ru/cars              403.0   602.0
avito.ru and am.ru                    262.0   579.0
e1.ru and auto.ru                     451.0   475.0
avito.ru and cars.mail.ru/sale        256.0   424.0
drom.ru and irr.ru/cars               277.0   423.0
auto.ru and irr.ru/cars               288.0   409.0
auto.ru and am.ru                     224.0   408.0
drom.ru and am.ru                     187.0   394.0
auto.ru and cars.mail.ru/sale         195.0   330.0
avito.ru and avtomarket.ru            205.0   299.0
drom.ru and cars.mail.ru/sale         189.0   292.0
drom.ru and avtomarket.ru             175.0   247.0
auto.ru and avtomarket.ru             162.0   243.0
e1.ru and irr.ru/cars                 148.0   235.0
e1.ru and am.ru                        99.0   224.0
am.ru and irr.ru/cars                   NaN   223.0
irr.ru/cars and cars.mail.ru/sale      94.0   197.0
am.ru and cars.mail.ru/sale             NaN   166.0
e1.ru and cars.mail.ru/sale           105.0   154.0
e1.ru and avtomarket.ru               105.0   139.0
avtomarket.ru and irr.ru/cars           NaN   139.0
avtomarket.ru and am.ru                72.0   133.0
avtomarket.ru and cars.mail.ru/sale    48.0   105.0
auto.ru and drom.ru                   799.0     NaN
cars.mail.ru/sale and am.ru            73.0     NaN
irr.ru/cars and am.ru                 102.0     NaN
irr.ru/cars and avtomarket.ru          73.0     NaN

Lalu saya membuat semua kombinasi terbalik - masalah terpecahkan. Tapi kenapa ada NaN? Mengapa kombinasi di 2014 dan 2015 berbeda?

Saya menambahkan ke fungsi f:

def f(df):
    print df['address'].unique()

    dfs = []
    i = 0
    for x in [list(x) for x in itertools.combinations((df['address'].unique()), 2)]:
...
...

dan hasilnya (mengapa pencetakan pertama dua kali dijelaskan di warning di sini ):

['avito.ru' 'e1.ru' 'drom.ru' 'auto.ru' 'avtomarket.ru' 'am.ru'
 'irr.ru/cars' 'cars.mail.ru/sale']
['avito.ru' 'e1.ru' 'drom.ru' 'auto.ru' 'avtomarket.ru' 'am.ru'
 'irr.ru/cars' 'cars.mail.ru/sale']
['avito.ru' 'e1.ru' 'auto.ru' 'drom.ru' 'irr.ru/cars' 'avtomarket.ru'
 'cars.mail.ru/sale' 'am.ru']

Jadi daftarnya berbeda dan kombinasinya juga berbeda -> Saya mendapatkan beberapa nilai NaN.

Solusinya adalah mengurutkan daftar kombinasi.

def f(df):
    #print (sorted(df['address'].unique()))   
    dfs = []
    for x in [list(x) for x in itertools.combinations(sorted(df['address'].unique()), 2)]:
        c1 = df.loc[df['address'].isin([x[0]]), 'ID']
        ...
        ...

Semua kode adalah:

import pandas as pd
import itertools

df = pd.read_csv("avito_trend.csv", 
                      parse_dates=[2])

def f(df):
    #print (sorted(df['address'].unique()))   
    dfs = []
    for x in [list(x) for x in itertools.combinations(sorted(df['address'].unique()), 2)]:
        c1 = df.loc[df['address'].isin([x[0]]), 'ID']
        c2 = df.loc[df['address'].isin([x[1]]), 'ID']
        c = pd.Series(list(set(c1).intersection(set(c2))))
        dfs.append(pd.DataFrame({'common users':len(c), 'pair of websites':' and '.join(x)}, index=[0]))
    return pd.concat(dfs)

common_users = df.groupby([df['used_at'].dt.year]).apply(f).reset_index(drop=True, level=1).reset_index()
#print common_users

graph_by_common_users = common_users.pivot(index='pair of websites', columns='used_at', values='common users')

#change order of columns
graph_by_common_users = graph_by_common_users[[2015,2014]]
graph_by_common_users = graph_by_common_users.sort_values(2014, ascending=False)
#print graph_by_common_users
ax = graph_by_common_users.plot(kind='barh', width=0.5, figsize=(10,20))
[label.set_rotation(25) for label in ax.get_xticklabels()]

rects = ax.patches 
labels = [int(round(graph_by_common_users.loc[i, y])) \
for y in graph_by_common_users.columns.tolist() \
for i in graph_by_common_users.index]

for rect, label in zip(rects, labels): 
    height = rect.get_height() 
    ax.text(rect.get_width()+20, rect.get_y() - 0.25 + rect.get_height(), label, fontsize=8)

    handles, labels = ax.get_legend_handles_labels()
    # sort both labels and handles by labels
    labels, handles = zip(*sorted(zip(labels, handles), key=lambda t: t[0]))
    ax.legend(handles, labels)   

Dan grafik:

grafik

person jezrael    schedule 30.03.2016
comment
apakah mungkin untuk menurunkan angkanya sedikit, karena ada yang digabungkan - person ldevyataykina; 30.03.2016
comment
dan cetak 2014 di atas 2015? - person ldevyataykina; 30.03.2016
comment
Oke, beri aku waktu. Namun masalah pertama telah terpecahkan, lihat edit. - person jezrael; 30.03.2016
comment
Dan bisakah di pojok kanan atas diubah urutannya ya. 2014 pertama dan 2015 berikutnya - person ldevyataykina; 30.03.2016
comment
Terima kasih banyak. Inilah yang saya inginkan. Jika saya memiliki pertanyaan tentang kode, bolehkah saya bertanya kepada Anda? - person ldevyataykina; 30.03.2016
comment
Oki, coba tanya, tapi sekarang saya jalan-jalan, mungkin nanti saya jawab - person jezrael; 30.03.2016
comment
Mengapa Anda membuat c_invert dan x[1],x[0] = x[0],x[1] ? - person ldevyataykina; 31.03.2016
comment
Terima kasih atas penjelasannya) Sangat jelas. Dan bisakah Anda mengatakan, apa yang Anda lakukan untuk meningkatkan keterampilan Anda? - person ldevyataykina; 31.03.2016
comment
Pengkodean, pengkodean, pengkodean... :) Pelajari dokumentasi sempurna dari panda, buku masak juga sempurna. Dan menjawab pertanyaan tentang pandas di StackOverflow. :) - person jezrael; 31.03.2016

Masalah Penyiapan DataFrame

Sepertinya DataFrame Anda tidak terstruktur seperti yang Anda inginkan. DataFrame Anda berisi 2014 dan 2015 sebagai nama header kolom bukan sebagai nilai baris pada indeks used_at. Juga used_at adalah nama indeks bukan label indeks dari baris pertama.

Anda dapat menguji kebenarannya dengan menjalankan:

import pandas as pd
from cStringIO import StringIO

text_data = '''
used_at            2014  2015
address                      
am.ru               621   273
auto.ru            1752  1595
avito.ru           5460  4631
avtomarket.ru       314   215
cars.mail.ru/sale   457   271
drom.ru            1934  1623
e1.ru              1654  1359
irr.ru/cars         619   426
'''

# Read in tabular data with used_at row as header
df = pd.read_table(StringIO(text_data), sep='\s+', index_col=0)
print 'DataFrame created with used_at row as header:'
print df
print 

# print df.used_at would cause AttributeError: 'DataFrame' object has no attribute 'used_at'
print 'df columns    :', df.columns
print 'df index name :', df.index.name
print

DataFrame created with used_at row as header:
                   2014  2015
used_at                      
address             NaN   NaN
am.ru               621   273
auto.ru            1752  1595
avito.ru           5460  4631
avtomarket.ru       314   215
cars.mail.ru/sale   457   271
drom.ru            1934  1623
e1.ru              1654  1359
irr.ru/cars         619   426

df columns    : Index([u'2014', u'2015'], dtype='object')
df index name : used_at
person tmthydvnprt    schedule 20.03.2016