ゼロを除くデータフレームの各列の最小値

元のデータフレームは次のようなテーブルです。

                        S1_r1_ctrl/     S1_r2_ctrl/     S1_r3_ctrl/
sp|P38646|GRP75_HUMAN   2.960000e-06    5.680000e-06    0.000000e+00
sp|O75694-2|NU155_HUMAN 2.710000e-07    0.000000e+00    2.180000e-07
sp|Q05397-2|FAK1_HUMAN  0.000000e+00    2.380000e-07    7.330000e-06
sp|O60671-2|RAD1_HUMAN  NaN             NaN             NaN

データフレームの各列でゼロよりも大きい最小値を探しています。このの例を使用しようとしました私の質問に答えるために。私のコードはこんな感じです:

df.ne(0).idxmin()。to_frame( 'pos')。assign(値=ラムダd:df.lookup(d.pos、d.index))

しかし、それでもゼロしか得られず、結果は次のようになります。

            pos                     value

S1_r1_ctrl/ sp|Q05397-2|FAK1_HUMAN  0.0
S1_r2_ctrl/ sp|O75694-2|NU155_HUMAN 0.0
S1_r3_ctrl/ sp|P38646|GRP75_HUMAN   0.0

これの代わりに:

            pos                     value
S1_r1_ctrl/ sp|O75694-2|NU155_HUMAN 2.710000e-07
S1_r2_ctrl/ sp|Q05397-2|FAK1_HUMAN  2.380000e-07
S1_r3_ctrl/ sp|O75694-2|NU155_HUMAN 2.180000e-07

データ型に問題があるかもしれないと思いますが、よくわかりません。 ne(0)はゼロを無視すると仮定しましたが、そうではありませんので、混乱します。そして、おそらく私が必要なものを見つけるためのもっと知的な方法があります。

6
画像ではなくテキストとしてデータフレームを投稿してください
追加された 著者 chrisz,
追加された 著者 Rushabh Mehta,

5 答え

設定

df = pd.DataFrame([[0, 0, 0],
                   [0, 10, 0],
                   [4, 0, 0],
                   [1, 2, 3]],
                  columns=['first', 'second', 'third'])

min(0) のマスクを使用する

df[df.gt(0)].min(0)

first     1.0
second    2.0
third     3.0
dtype: float64

@DSMが指摘したように、これも書くことができます:

df.where(df.gt(0)).min(0)

パフォーマンス<//em>

def chris():
    df1[df1.gt(0)].min(0)

def chris2():
    df1.where(df1.gt(0)).min(0)

def wen():
    a=df1.values.T
    a = np.ma.masked_equal(a, 0.0, copy=False)
    a.min(1)

def haleemur():
    df1.replace(0, np.nan).min()

設定

from timeit import timeit
import matplotlib.pyplot as plt

res = pd.DataFrame(
       index=['chris', 'chris2', 'wen', 'haleemur'],
       columns=[10, 50, 100, 500, 1000, 5000, 10000, 50000, 100000],
       dtype=float
)

for f in res.index: 
    for c in res.columns:
        df1 = df.copy()
        df1 = pd.concat([df1]*c)
        stmt = '{}()'.format(f)
        setp = 'from __main__ import df1, {}'.format(f)
        res.at[f, c] = timeit(stmt, setp, number=50)

ax = res.div(res.min()).T.plot(loglog=True) 
ax.set_xlabel("N"); 
ax.set_ylabel("time (relative)");

plt.show()

結果

enter image description here

6
追加された
進むべき道だ。すべての列を通してリストの内包表記よりも軸を探索する方が得策
追加された 著者 RafaelC,
どうもありがとうございました:-)
追加された 著者 Wen,
意図されたマスクを表現することはより良い仕事をすると思うので、本当に意味的にだけです。
追加された 著者 DSM,
代わりに df.where を使用したことがありますが、これが正しい方法です。
追加された 著者 DSM,
先端をありがとう!ここで where の利点は何ですか?
追加された 著者 chrisz,
単に "より大きい"を意味します。 df.gt(0)df> 0 と同じです
追加された 著者 chrisz,
これは私のやり方よりずっと優れています。 +1
追加された 著者 Harv Ipan,
皆さん、df.gt()が何であるかを説明してください。そのための明確な文書が見つからない
追加された 著者 Polina Novikova,

多分 numpy が良い選択肢です

a=df.values.T
a = np.ma.masked_equal(a, 0.0, copy=False)
a.min(1)
Out[755]: 
masked_array(data=[1, 2, 3],
             mask=[False, False, False],
       fill_value=999999,
            dtype=int64)
5
追加された

すべての列をループ処理し、0なしの系列の最小値を見つける必要があります。

df = pd.DataFrame([[0, 0, 0],
                   [0, 10, 0],
                   [4, 0, 0],
                   [1, 2, 3]],
                  columns=['first', 'second', 'third'])

[df[col][df[col].ne(0)].min() for col in df.columns]

出力:

[1, 2, 3]
4
追加された
この出力は何ですか?
追加された 著者 RafaelC,
@ RafaelC、OPは最小限の入力で別のSO質問へのリンクを持っていました。私は混乱を避けるためにそれを答えに加えました。
追加された 著者 Harv Ipan,

別のオプションは 0np.nan に置き換えてから min メソッドを適用することです。

note: this doesn't address the > 0 condidtion, but the test frame seems to be only non-negative values.

他と同じ設定を使用します。

df = pd.DataFrame([[0, 0, 0],
                   [0, 10, 0],
                   [4, 0, 0],
                   [1, 2, 3]],
                  columns=['first', 'second', 'third'])

df.replace(0, np.nan).min()

first     1.0
second    2.0
third     3.0
dtype: float64

優れた回答よりもわずかに速いことがわかったので、この選択肢を投稿.com/users/3483203/user3483203 "> user3483203 、これもこの問題に対する私の最初の本能でした


%timeit df.replace(0, np.nan).min()
745 µs ± 2.72 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit df[df > 0].min()
1.09 ms ± 14.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

次の点にも注意してください。

%timeit df[df != 0].min()
1.1 ms ± 16.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

そのため、集計の計算時に範囲ではなく特定の値を無視する必要がある場合は、 np.nanreplace を指定しますパフォーマンスへの道

3
追加された
今それを証明することはできませんが、これが大きいdfのためにまだ速いかどうかわからない df.gt(0)が速くなると思いますか
追加された 著者 RafaelC,
ベンチマークを上げてくれてありがとう@ user3483203!
追加された 著者 Haleemur Ali,
@さて、あなたのソリューションのためのタイミングを絶対に加えるでしょう:)今すぐテストセットアップを作成します。
追加された 著者 Haleemur Ali,
パフォーマンスプロファイルは一般の人々に役立つ可能性があるので、可能であればベンチマークを実行してすぐにチャートを掲載する
追加された 著者 Haleemur Ali,
あなたは私の方法のためのタイミングを加えてください、それについてちょうど興味があります。あなたにもありがとう、あなたの追加の完璧な仕事に投票してください
追加された 著者 Wen,
@私の答えに加えて、あなたはすべてのデータフレームサイズで勝ちます。
追加された 著者 chrisz,

各列で試してください:

    df.value.min(skipna=True)
1
追加された
skipna = Trueがデフォルトです。ゼロと負の値はnullではないため、これは> 0条件に対処しません。
追加された 著者 DSM,
df.min()と同じ0が表示されます。
追加された 著者 Polina Novikova,