Мы можем использовать общий метод преобразования DataTable
в List
вместо того, чтобы вручную преобразовывать DataTable
в List
.
Примечание: DataTable
's ColumnName
и Type
's PropertyName
должен быть таким же.
Вызвать ниже Метод:
long result = Utilities.ConvertTo<Student>(dt ,out listStudent);
// Generic Method
public class Utilities
{
public static long ConvertTo<T>(DataTable table, out List<T> entity)
{
long returnCode = -1;
entity = null;
if (table == null)
{
return -1;
}
try
{
entity = ConvertTo<T>(table.Rows);
returnCode = 0;
}
catch (Exception ex)
{
returnCode = 1000;
}
return returnCode;
}
static List<T> ConvertTo<T>(DataRowCollection rows)
{
List<T> list = null;
if (rows != null)
{
list = new List<T>();
foreach (DataRow row in rows)
{
T item = CreateItem<T>(row);
list.Add(item);
}
}
return list;
}
static T CreateItem<T>(DataRow row)
{
string str = string.Empty;
string strObj = string.Empty;
T obj = default(T);
if (row != null)
{
obj = Activator.CreateInstance<T>();
strObj = obj.ToString();
NameValueCollection objDictionary = new NameValueCollection();
foreach (DataColumn column in row.Table.Columns)
{
PropertyInfo prop = obj.GetType().GetProperty(column.ColumnName);
if (prop != null)
{
str = column.ColumnName;
try
{
objDictionary.Add(str, row[str].ToString());
object value = row[column.ColumnName];
Type vType = obj.GetType();
if (value == DBNull.Value)
{
if (vType == typeof(int) || vType == typeof(Int16)
|| vType == typeof(Int32)
|| vType == typeof(Int64)
|| vType == typeof(decimal)
|| vType == typeof(float)
|| vType == typeof(double))
{
value = 0;
}
else if (vType == typeof(bool))
{
value = false;
}
else if (vType == typeof(DateTime))
{
value = DateTime.MaxValue;
}
else
{
value = null;
}
prop.SetValue(obj, value, null);
}
else
{
prop.SetValue(obj, value, null);
}
}
catch(Exception ex)
{
}
}
}
PropertyInfo ActionProp = obj.GetType().GetProperty("ActionTemplateValue");
if (ActionProp != null)
{
object ActionValue = objDictionary;
ActionProp.SetValue(obj, ActionValue, null);
}
}
return obj;
}
}
Прежде всего, не используйте 3D-график, когда 2D-график будет достаточным, что в этом случае будет. Использование 3D-графиков для 2D-данных излишне запутывает вещи.
Во-вторых, вы можете использовать комбинацию данных MultiIndex Pandas, чтобы получить желаемый результат:
df = pd.DataFrame({
'a': list(range(5))*3,
'b': [1, 2, 3]*5,
'c': np.random.randint(low=0, high=10, size=15)
}).set_index(['a', 'b'])
fig, ax = plt.subplots(figsize=(10,6))
y_errs = np.random.random(size=(3, 5))
df.unstack().plot.bar(ax=ax, yerr=y_errs)
Насколько я знаю, не существует прямого способа сделать это в 3d. Однако вы можете создать обходное решение, как показано ниже. Решение вдохновлено из здесь . Хитрость заключается в том, чтобы пройти две точки, лежащие вертикально, а затем использовать _
в качестве маркера, чтобы действовать в качестве заглушки для ошибки.
yerr=np.array([10,10,10,10,10,10,10,10,10,10])
for n, i in enumerate(df_3d):
xs = np.arange(len(df_3d[i]))
ys = [i for i in df_3d[i]]
zs = z[n]
cs = colors[n]
ax.bar(xs, ys, zs, zdir='y', color=cs, alpha=0.8)
for i, j in enumerate(ys):
ax.plot([xs[i], xs[i]], [zs, zs], [j+yerr[i], j-yerr[i]], marker="_", color=cs)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')