Как условно отсортировать значения оси X на графике Matplotlib? - PullRequest
0 голосов
/ 25 марта 2019

У меня есть следующий DataFrame:

file     size
abc1.txt  2.1 MB
abc2.txt  1.0 MB
abc3.txt  1.5 MB
abc4.txt  767.9 KB

Когда я строю эти данные (plt.plot(df['file'],df['size'])), значения КБ и МБ, очевидно, неправильно упорядочены и перепутаны. Как их отсортировать, чтобы сортировка начиналась с КБ и продолжалась с МБ?

767.9 KB  1.0 MB  1.5 MB  2.1 MB

Ответы [ 2 ]

2 голосов
/ 26 марта 2019
df = pd.DataFrame({'file': [1,2,3,4], 'size': ['2.1 MB', '1.0 MB', '1.5 MB', '767.9 KB']})
cv= {'': 1, 'KB': 1e1, 'MB': 1e6, 'GB': 1e9, 'TB': 1e12}
df['size_bytes'] = df['size'].apply(lambda x: float(x.split()[0])*cv[x.split()[1]] 
                                    if len(x.split())==2 else float(x))
fig, ax = plt.subplots()
plt.plot(df['file'],df['size_bytes'])

И если вы хотите, чтобы ось у была в читабельном виде

def to_human_readable(size):
    power = 1000
    n = 0
    mem = {0 : '', 1: 'KB', 2: 'MB', 3: 'GB', 4: 'TB'}
    while size > power:
        size /=  power
        n += 1
    return "{0} {1}".format(size, mem[n])

ax.set_yticklabels([to_human_readable(v) if v >= 0 else ' ' for v in  
                    ax.get_yticks(minor=False)])

enter image description here

(в цифровом хранилище 1kb = 1000)

1 голос
/ 26 марта 2019

Сначала он читает ваши числа в виде строки, поэтому любой порядок не имеет особого смысла, и, кроме того, расстояние между точками не является репрезентативным.

Также в целом я бы сказал, что это плохая практикаиметь разные единицы на одной оси.Лучше перевести в одну единицу:

import matplotlib.pyplot as plt
import pandas as pd

df = pd.DataFrame([['abc1.txt',  '2.1 MB'],
                   ['abc2.txt',  '1.0 MB'],
                   ['abc3.txt',  '1.5 MB'],
                   ['abc4.txt',  '767.9 KB']], columns=["file", 'size'])

# This is a list comprehension that splits the number out of the string, converts it to a float, 
# and divides it by 1000 if the other part of the string is 'KB'.
df['size_float'] = [float(x[0])/1000 if x[1]=='KB' else float(x[0]) for x in df['size'].str.split()]
plt.plot(df['file'],df['size_float'])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...