我想使用pandas
的下拉菜单来绘制ipywidgets
数据帧的子集,但出现一些奇怪的错误。
import ipywidgets as wg
from IPython.display import display
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# Make Data Frame
#
df = pd.DataFrame({
"x": np.arange(32),
"y": np.arange(32),
"A": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
"B": [0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1],
"C": [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1]
})
# Make dropdown menus
#
w1 = wg.Dropdown(
options=[0,1],
value=0,
description='A:',
)
#
w2 = wg.Dropdown(
options=[0,1],
value=0,
description='B:',
)
#
w3 = wg.Dropdown(
options=[0,1],
value=0,
description='C:',
)
#
w4 = wg.Dropdown(
options=['df'],
value='df',
description='DF:',
)
# Define plotting function
#
def myPlot(df, a, b, c):
print(df)
print(a)
print(b)
print(c)
x = df["x"][df["A"]==a & df["B"]==b & df["C"]==c]
y = df["y"][df["A"]==a & df["B"]==b & df["C"]==c]
plt.scatter(x,y)
plt.show()
# Plot with interactive dropdown menus
#
wg.interact(myPlot, df=w4, a=w1, b=w2, c=w3)
当我尝试在绘图函数x
中定义TypeError: string indices must be integers
时发生错误。我认为这与将数据帧放入绘图函数有关,因为绘图函数中的print
命令为我提供了A
,B
和{{1 }},但显示字符串C
。
如何获取我想要的情节?
答案 0 :(得分:1)
我不会尝试使用字符串从名称空间中提取变量。
我将包装您的交互器并直接传递数据框:
import ipywidgets as wg
from IPython.display import display
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# Make Data Frame
#
df = pd.DataFrame({
"x": np.arange(32),
"y": np.arange(32),
"A": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
"B": [0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1],
"C": [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1]
})
# Make dropdown menus
#
w1 = wg.Dropdown(
options=[0,1],
value=0,
description='A:',
)
#
w2 = wg.Dropdown(
options=[0,1],
value=0,
description='B:',
)
#
w3 = wg.Dropdown(
options=[0,1],
value=0,
description='C:',
)
# Define plotting function
#
def myPlot(df, a, b, c):
subset = df.loc[df["A"].eq(a) & df["B"].eq(b) & df["C"].eq(c), :]
fig, ax = plt.subplots()
ax.scatter("x", "y", data=subset)
return fig
def interactive_plotter(df):
df_widget = wg.fixed(df)
return wg.interact(myPlot, df=df_widget, a=w1, b=w2, c=w3)
fig = interactive_plotter(df)
要考虑的另一件事是您的链接逻辑语句:
逻辑运算符的操作顺序不是很直观
此声明:
x = df["x"][df["A"]==a & df["B"]==b & df["C"]==c]
评估为:
x = df["x"][df["A"] == (a & df["B"]) == (b & df["C"]==c)]
(或接近它的地方)。
您想要的至少是:
x = df["x"][(df["A"] == a) & (df["B"] == b) & (df["C"] == c)]
但是我认为最好使用.loc
访问器:
x = df.loc[(df["A"] == a) & (df["B"] == b) & (df["C"] == c), "x"]
如果您不喜欢所有这些括号,也可以使用.eq()
x = df.loc[df["A"].eq(a) & df["B"].eq(b) & df["C"].eq(c), "x"]
答案 1 :(得分:0)
如果您确实希望在不同的数据框之间切换以进行绘制,请将其放入字典中,为每个数据框赋予唯一的字符串键,然后将该字典作为选项传递给下拉列表。
import ipywidgets as wg
from IPython.display import display
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# Make Data Frame
#
df = pd.DataFrame({
"x": np.arange(32),
"y": np.arange(32),
"A": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
"B": [0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1],
"C": [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1]
})
choices = {
'df': df
}
# Make dropdown menus
#
w1 = wg.Dropdown(
options=[0,1],
value=0,
description='A:',
)
#
w2 = wg.Dropdown(
options=[0,1],
value=0,
description='B:',
)
#
w3 = wg.Dropdown(
options=[0,1],
value=0,
description='C:',
)
#
w4 = wg.Dropdown(
options=['df'],
value='df',
description='DF:',
)
# Define plotting function
#
def myPlot(df_name, a, b, c):
df = choices[df_name]
x = df.loc[(df["A"]==a) & (df["B"]==b) & (df["C"]==c)]["x"]
y = df.loc[(df["A"]==a) & (df["B"]==b) & (df["C"]==c)]["y"]
plt.scatter(x,y)
plt.show()
# Plot with interactive dropdown menus
#
wg.interact(myPlot, df_name=w4, a=w1, b=w2, c=w3)
PS。同样,对DataFrame的索引调用的顺序错误。 1)过滤行,然后2)选择所需的列。
df.loc[(df["A"]==a) & (df["B"]==b) & (df["C"]==c)]["x"] # correct order
df['x'].loc[(df["A"]==a) & (df["B"]==b) & (df["C"]==c)] # incorrect order