想要将Pandas Dataframe绘制为具有log10刻度x轴的多个直方图

Sim*_*ard 10 python logarithm matplotlib histogram pandas

我在Pandas数据帧中有浮点数据.每列代表一个变量(它们具有字符串名称),每一行代表一组值(这些行具有不重要的整数名称).

>>> print data
0      kppawr23    kppaspyd
1      3.312387   13.266040
2      2.775202    0.100000
3    100.000000  100.000000
4    100.000000   39.437420
5     17.017150   33.019040
...
Run Code Online (Sandbox Code Playgroud)

我想为每列绘制直方图.我实现的最好结果是使用了dataframe的hist方法:

data.hist(bins=20)
Run Code Online (Sandbox Code Playgroud)

但我希望每个直方图的x轴都是log10刻度.并且bin上的bin也是log10,但这很容易使用bins = np.logspace(-2,2,20).

一种解决方法可能是在绘图之前对log10进行数据转换,但是我尝试过的方法,

data.apply(math.log10)
Run Code Online (Sandbox Code Playgroud)

data.apply(lambda x: math.log10(x))
Run Code Online (Sandbox Code Playgroud)

给我一个浮点错误.

    "cannot convert the series to {0}".format(str(converter)))
TypeError: ("cannot convert the series to <type 'float'>", u'occurred at index kppawr23')
Run Code Online (Sandbox Code Playgroud)

unu*_*tbu 7

你可以用

ax.set_xscale('log')
Run Code Online (Sandbox Code Playgroud)

data.hist()返回一个轴数组.你需要调用 ax.set_xscale('log')每个轴,ax使每个轴都进行对数缩放.


例如,

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
np.random.seed(2015)

N = 100
arr = np.random.random((N,2)) * np.logspace(-2,2,N)[:, np.newaxis]
data = pd.DataFrame(arr, columns=['kppawr23', 'kppaspyd'])

bins = np.logspace(-2,2,20)
axs = data.hist(bins=bins)
for ax in axs.ravel():
    ax.set_xscale('log')

plt.gcf().tight_layout()
plt.show()
Run Code Online (Sandbox Code Playgroud)

产量

在此输入图像描述


顺便说一句,要获取DataFrame中每个值的日志data,您可以使用

logdata = np.log10(data)
Run Code Online (Sandbox Code Playgroud)

因为NumPy ufuncs(例如np.log10)可以应用于pandas DataFrames,因为它们对DataFrame中的所有值进行元素操作.

data.apply(math.log10)因为apply尝试将整个列(一系列)的值传递给,所以无效math.log10.math.log10只需要一个标量值.

data.apply(lambda x: math.log10(x))失败的原因与此相同data.apply(math.log10).而且,如果data.apply(func)并且data.apply(lambda x: func(x))都是可行的选项,那么第一个应该是首选的,因为lambda函数只会使调用变慢.

您可以data.apply(np.log10)再次使用,因为NumPy ufunc np.log10可以应用于Series,但是没有理由在np.log10(data)工作时打扰这样做.

你也可以使用data.applymap(math.log10),因为applymap电话 math.log10在每个值data一个-AT-A-时间.但是这比np.log10在整个DataFrame上调用等效的NumPy函数要慢得多.不过,applymap如果你需要调用一些不是ufunc的自定义函数,还是值得了解的.