Ita*_*vni 4 colors matplotlib python-3.x pandas
我有一个包含两列的熊猫数据框。列值之一需要映射到十六进制颜色。另一个绘图过程从那里接管。
这是我到目前为止所尝试的。部分玩具代码取自此处。
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
# Create dataframe
df = pd.DataFrame(np.random.randint(0,21,size=(7, 2)), columns=['some_value', 'another_value'])
# Add a nan to handle realworld
df.iloc[-1] = np.nan
# Try to map values to colors in hex
# # Taken from here
norm = matplotlib.colors.Normalize(vmin=0, vmax=21, clip=True)
mapper = plt.cm.ScalarMappable(norm=norm, cmap=plt.cm.viridis)
df['some_value_color'] = df['some_value'].apply(lambda x: mapper.to_rgba(x))
df
Run Code Online (Sandbox Code Playgroud)
哪些输出:
如何'some_value' 一次性将df 列值转换为十六进制?理想情况下使用sns.cubehelix_palette(light=1)
我不反对使用除 matplotlib
提前致谢。
您可以使用matplotlib.colors.to_hex()将颜色转换为十六进制表示。
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import seaborn as sns
# Create dataframe
df = pd.DataFrame(np.random.randint(0,21,size=(7, 2)), columns=['some_value', 'another_value'])
# Add a nan to handle realworld
df.iloc[-1] = np.nan
# Try to map values to colors in hex
# # Taken from here
norm = matplotlib.colors.Normalize(vmin=0, vmax=21, clip=True)
mapper = plt.cm.ScalarMappable(norm=norm, cmap=plt.cm.viridis)
df['some_value_color'] = df['some_value'].apply(lambda x: mcolors.to_hex(mapper.to_rgba(x)))
df
Run Code Online (Sandbox Code Playgroud)
上面的方法很容易使用,但可能不是很有效。下面让我们比较一些替代方案。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
def create_df(n=10):
# Create dataframe
df = pd.DataFrame(np.random.randint(0,21,size=(n, 2)),
columns=['some_value', 'another_value'])
# Add a nan to handle realworld
df.iloc[-1] = np.nan
return df
Run Code Online (Sandbox Code Playgroud)
以下是上面的解决方案。它逐行将转换应用于数据帧。这相当低效。
def apply1(df):
# map values to colors in hex via
# matplotlib to_hex by pandas apply
norm = mcolors.Normalize(vmin=np.nanmin(df['some_value'].values),
vmax=np.nanmax(df['some_value'].values), clip=True)
mapper = plt.cm.ScalarMappable(norm=norm, cmap=plt.cm.viridis)
df['some_value_color'] = df['some_value'].apply(lambda x: mcolors.to_hex(mapper.to_rgba(x)))
return df
Run Code Online (Sandbox Code Playgroud)
这就是为什么我们可能会选择首先将值计算到一个 numpy 数组中,然后将该数组分配为新创建的列。
def apply2(df):
# map values to colors in hex via
# matplotlib to_hex by assigning numpy array as column
norm = mcolors.Normalize(vmin=np.nanmin(df['some_value'].values),
vmax=np.nanmax(df['some_value'].values), clip=True)
mapper = plt.cm.ScalarMappable(norm=norm, cmap=plt.cm.viridis)
a = mapper.to_rgba(df['some_value'])
df['some_value_color'] = np.apply_along_axis(mcolors.to_hex, 1, a)
return df
Run Code Online (Sandbox Code Playgroud)
最后,我们可以使用从 matplotlib 颜色图创建的查找表 (LUT),并通过规范化数据索引 LUT。由于此解决方案需要先创建 LUT,因此对于条目少于 LUT 颜色的数据帧来说,效率相当低,但对于大型数据帧来说会有所回报。
def apply3(df):
# map values to colors in hex via
# creating a hex Look up table table and apply the normalized data to it
norm = mcolors.Normalize(vmin=np.nanmin(df['some_value'].values),
vmax=np.nanmax(df['some_value'].values), clip=True)
lut = plt.cm.viridis(np.linspace(0,1,256))
lut = np.apply_along_axis(mcolors.to_hex, 1, lut)
a = (norm(df['some_value'].values)*255).astype(np.int16)
df['some_value_color'] = lut[a]
return df
Run Code Online (Sandbox Code Playgroud)
比较时间
让我们以一个包含 10000 行的数据帧为例。
df = create_df(10000)
原始解决方案(apply1)
%timeit apply1(df)
2.66 s per loop
Run Code Online (Sandbox Code Playgroud)阵列解决方案(apply2)
%timeit apply2(df)
240 ms per loop
Run Code Online (Sandbox Code Playgroud)LUT 解决方案(apply3)
%timeit apply1(df)
7.64 ms per loop
Run Code Online (Sandbox Code Playgroud)在这种情况下,LUT 解决方案提供了近 400 倍的改进。
| 归档时间: |
|
| 查看次数: |
2069 次 |
| 最近记录: |