pandas - 从 pandas 数据框中获取值,修改它们并将它们附加到新的 dataframe/np.array
问题描述
我有点坚持以下事情:
我正在尝试从数据框中获取值pandas
,对其进行修改,然后放入新的dataframe
/ np.array
。
特别是数据框df1
看起来像这样:
1. 0 0 ... 0.5 0.5 .. 0
2. 0 0 ... 0 1 .. 0
3. 0.5 0 ... 0 0.5 .. 0
...
即我有很多零条目,除了一些总和为一的非零条目。
我想要做的是每行(向量),用uniform
在一些低值和非零条目之间的最小值之间的分布所取的值修改零条目,然后将结果附加到新的数据帧或 numpy大批。
我们可以调用的结果df2
应该是这样的:
1. 0.22 0.15 ... 0.5 0.5 .. 0.004
2. 0.7 0.654 ... 0.0567 1 .. 0.45
3. 0.5 0.432 ... 0.354 0.5 .. 0.0432
...
我正在尝试使用以下代码:
arr = np.array([[]])
for j in range(len(df1)):
for i in range(103): #103 is the length of these vectors
if df1.iloc[j][i] == 0:
arr=np.append([np.random.uniform(low=0.01, high=df1.iloc[j][3:].min()), arr])
else:
arr[j][i]= df1.iloc[j][i]
我得到的是以下错误:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-256-141abfd58de1> in <module>
3 for j in range(len(data)):
4 for i in range(103):
----> 5 if data.iloc[j][i] == 0:
6 arr=np.append([np.random.uniform(low=0.01, high=data.iloc[j][3:].min()), arr])
7 else:
~\anaconda3\lib\site-packages\pymatgen\core\composition.py in __eq__(self, other)
167 # in the elmap, so checking len enables us to only check one
168 # compositions elements
--> 169 if len(self) != len(other):
170 return False
171 for el, v in self.items():
TypeError: object of type 'int' has no len()
非常感谢,
詹姆士
解决方案
首先,让我们创建一个df1
有 10 行和 103 列的大多数为零且所有行总和为 1 的 a:
>>> df1 = pd.DataFrame({r: {val: np.random.randint(20) for val in np.random.choice(np.arange(103), np.random.randint(2, 5))} for r in range(10)}).T
>>> df1 = df1.div(df1.sum(axis='columns'), axis='index').reindex(columns=np.arange(103)).fillna(0)
让我们通过查看数据、汇总行和每行计数零来检查我们做了什么:
>>> df1
0 1 2 3 4 5 ... 97 98 99 100 101 102
0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.000
1 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.000
2 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.000
3 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.000
4 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.000
5 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.1 0.0 0.0 0.0 0.0 0.475
6 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.000
7 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.000
8 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.000
9 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.000
[10 rows x 103 columns]
>>> df1.sum(axis='columns')
0 1.0
1 1.0
2 1.0
3 1.0
4 1.0
5 1.0
6 1.0
7 1.0
8 1.0
9 1.0
dtype: float64
>>> df1.ne(0).sum(axis='columns').astype(int)
0 3
1 2
2 3
3 2
4 3
5 4
6 4
7 3
8 3
9 3
dtype: int64
因此,这似乎尊重您的规格df1
,现在我们可以开始工作了。
首先,让我们屏蔽所有零,因此我们有一个数据框来提取最小非零值:
>>> df1_nz = df1.mask(df1.eq(0))
>>> df1_nz.min(axis='columns')
0 0.282051
1 0.210526
2 0.181818
3 0.464286
4 0.272727
5 0.100000
6 0.068182
7 0.185185
8 0.050000
9 0.222222
dtype: float64
现在从那里 min 我们可以np.uniform
每行调用一次以获得一个充满随机值的数据帧,并使用这些随机值填充 df1 非零:
>>> random_vals = pd.DataFrame({
... r: np.random.uniform(0.01, n, 103) for r, n in df1_nz.min(axis='columns').iteritems()
... }, index=df1.columns).T
>>> df2 = df1_nz.fillna(random_vals)
>>> df2
0 1 2 3 ... 99 100 101 102
0 0.274312 0.119229 0.200223 0.126925 ... 0.250511 0.076387 0.262691 0.091327
1 0.178858 0.032533 0.171083 0.187775 ... 0.104859 0.141225 0.145604 0.024747
2 0.149279 0.095146 0.067775 0.074993 ... 0.167393 0.109034 0.082226 0.146610
3 0.101093 0.391821 0.266622 0.336723 ... 0.126007 0.438758 0.321557 0.339710
4 0.037873 0.250409 0.123596 0.152685 ... 0.086009 0.190996 0.086574 0.253784
5 0.051473 0.032933 0.085726 0.064984 ... 0.064354 0.050978 0.086429 0.475000
6 0.043807 0.021605 0.049259 0.060036 ... 0.043379 0.052804 0.039904 0.044067
7 0.033173 0.030694 0.178263 0.042904 ... 0.183436 0.019724 0.024167 0.074844
8 0.019714 0.019226 0.028672 0.046260 ... 0.023111 0.042002 0.028637 0.018817
9 0.137686 0.101749 0.127393 0.026675 ... 0.083874 0.197242 0.170042 0.143624
[10 rows x 103 columns]
如果我们在 df1 非零的位置过滤 df2,我们可以看到它仍然是相同的值:
>>> df2.where(df1.ne(0)).stack()
0 56 0.410256
58 0.307692
77 0.282051
1 13 0.210526
77 0.789474
2 25 0.181818
51 0.636364
92 0.181818
3 19 0.535714
74 0.464286
4 18 0.454545
33 0.272727
91 0.272727
5 38 0.200000
54 0.225000
97 0.100000
102 0.475000
6 7 0.409091
12 0.068182
30 0.250000
73 0.272727
7 18 0.518519
57 0.185185
69 0.296296
8 7 0.050000
40 0.250000
90 0.700000
9 20 0.259259
38 0.518519
89 0.222222
dtype: float64
你没有解释,[3:]
所以我会忽略它,但你可以用这个方法重新引入它df1_nz = df1.mask(…)[df1.columns[3:]]
。
推荐阅读
- c++ - 谷歌云语音到文本 C++
- r - R中的聚集堆积条形图
- c# - 如何将值从 View 传递到 .doc 模板?
- c# - 由于 DataGridView 中的空白单元格,我收到数据类型不匹配错误
- javascript - 根据在另一个选择下拉列表中选择的年份动态显示选择下拉列表中剩余的可用月份
- arrays - 有人可以为我更深入地解释 Scala 中关于数组的不变性/可变性概念吗?
- javascript - 调用 stopBackgroundTimer 时 React Native runBackgroundTimer 不会停止
- c# - 如何使用 FluentAssertions 检查对象是否从另一个类继承?
- reactjs - 如何在注册流程中管理状态(ReactJS)
- python - 有没有办法将 Microsoft C/C++ UIAutomationCore.dll 导入 Python?